elCaribe app - customization and branding
This commit is contained in:
407
news-app/lib/ui/screens/HomePage/HomePage.dart
Normal file
407
news-app/lib/ui/screens/HomePage/HomePage.dart
Normal file
@@ -0,0 +1,407 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:location/location.dart' as loc;
|
||||
import 'package:marqueer/marqueer.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/Auth/authCubit.dart';
|
||||
import 'package:news/cubits/Auth/registerTokenCubit.dart';
|
||||
import 'package:news/cubits/Bookmark/bookmarkCubit.dart';
|
||||
import 'package:news/cubits/LikeAndDislikeNews/LikeAndDislikeCubit.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
import 'package:news/cubits/breakingNewsCubit.dart';
|
||||
import 'package:news/cubits/featureSectionCubit.dart';
|
||||
import 'package:news/cubits/generalNewsCubit.dart';
|
||||
import 'package:news/cubits/getUserDataByIdCubit.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/cubits/languageJsonCubit.dart';
|
||||
import 'package:news/cubits/liveStreamCubit.dart';
|
||||
import 'package:news/cubits/otherPagesCubit.dart';
|
||||
import 'package:news/cubits/sectionByIdCubit.dart';
|
||||
import 'package:news/cubits/settingCubit.dart';
|
||||
import 'package:news/cubits/weatherCubit.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/data/models/authorModel.dart';
|
||||
import 'package:news/data/repositories/SectionById/sectionByIdRepository.dart';
|
||||
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/GeneralNewsRandomStyle.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/LiveWithSearchView.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionShimmer.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/WeatherData.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle1.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle2.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle3.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle4.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle5.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/SectionStyle6.dart';
|
||||
import 'package:news/ui/screens/Profile/Widgets/customAlertDialog.dart';
|
||||
import 'package:news/ui/widgets/SnackBarWidget.dart';
|
||||
import 'package:news/ui/widgets/adSpaces.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/ui/widgets/errorContainerWidget.dart';
|
||||
import 'package:news/utils/ErrorMessageKeys.dart';
|
||||
import 'package:news/utils/hiveBoxKeys.dart';
|
||||
import 'package:news/utils/strings.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/data/models/AuthModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
HomeScreenState createState() => HomeScreenState();
|
||||
}
|
||||
|
||||
class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
|
||||
late final ScrollController featuredSectionsScrollController = ScrollController()..addListener(hasMoreFeaturedSectionsScrollListener);
|
||||
|
||||
final loc.Location _location = loc.Location();
|
||||
bool? _serviceEnabled;
|
||||
loc.PermissionStatus? _permissionGranted;
|
||||
double? lat;
|
||||
double? lon;
|
||||
bool updateList = false;
|
||||
Set<String> get locationValue => SettingsLocalDataRepository().getLocationCityValues();
|
||||
late final appConfig, authConfig;
|
||||
String languageId = "14"; //set it as default language code
|
||||
|
||||
void getSections() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<SectionCubit>().getSection(langId: languageId, latitude: locationValue.first, longitude: locationValue.last);
|
||||
}).whenComplete(() => getGeneralNews());
|
||||
}
|
||||
|
||||
void getLiveStreamData() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<LiveStreamCubit>().getLiveStream(langId: languageId);
|
||||
});
|
||||
}
|
||||
|
||||
void getBookmark() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<BookmarkCubit>().getBookmark(langId: languageId);
|
||||
});
|
||||
}
|
||||
|
||||
void getLikeNews() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<LikeAndDisLikeCubit>().getLike(langId: languageId);
|
||||
});
|
||||
}
|
||||
|
||||
void getUserData() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<GetUserByIdCubit>().getUserById();
|
||||
});
|
||||
}
|
||||
|
||||
checkForAppUpdate() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (context.read<AppConfigurationCubit>().state is AppConfigurationFetchSuccess) {
|
||||
if (context.read<AppConfigurationCubit>().isUpdateRequired()) {
|
||||
openUpdateDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openUpdateDialog() {
|
||||
bool isForceUpdate = (context.read<AppConfigurationCubit>().getForceUpdateMode() != "" && context.read<AppConfigurationCubit>().getForceUpdateMode() == "1") ? true : false;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setStater) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
child: CustomAlertDialog(
|
||||
isForceAppUpdate: (isForceUpdate) ? true : false,
|
||||
context: context,
|
||||
yesButtonText: 'yesLbl',
|
||||
yesButtonTextPostfix: '',
|
||||
noButtonText: (isForceUpdate) ? 'exitLbl' : 'noLbl',
|
||||
imageName: '',
|
||||
titleWidget: CustomTextLabel(
|
||||
text: (isForceUpdate) ? 'forceUpdateTitleLbl' : 'newVersionAvailableTitleLbl',
|
||||
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w800, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
messageText: context.read<LanguageJsonCubit>().getTranslatedLabels((isForceUpdate) ? 'forceUpdateDescLbl' : 'newVersionAvailableDescLbl'),
|
||||
onYESButtonPressed: () => UiUtils.gotoStores(context)),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showPermissionPopup() async {
|
||||
loc.LocationData locationData;
|
||||
|
||||
_serviceEnabled = await _location.serviceEnabled();
|
||||
if (!_serviceEnabled!) {
|
||||
_serviceEnabled = await _location.requestService();
|
||||
if (!_serviceEnabled!) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_permissionGranted = await _location.hasPermission();
|
||||
if (_permissionGranted == loc.PermissionStatus.denied) {
|
||||
SettingsLocalDataRepository().setLocationCityKeys(null, null);
|
||||
_permissionGranted = await _location.requestPermission();
|
||||
if (_permissionGranted != loc.PermissionStatus.granted) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
locationData = await _location.getLocation();
|
||||
|
||||
setState(() {
|
||||
lat = locationData.latitude;
|
||||
lon = locationData.longitude;
|
||||
});
|
||||
getLocationPermission();
|
||||
|
||||
return (locationData);
|
||||
}
|
||||
|
||||
getLocationPermission() async {
|
||||
if (appConfig.getLocationWiseNewsMode() == "1") {
|
||||
SettingsLocalDataRepository().setLocationCityKeys(lat, lon);
|
||||
//update latitude,longitude - along with token
|
||||
if (context.read<SettingsCubit>().getSettings().token != '') {
|
||||
context.read<RegisterTokenCubit>().registerToken(fcmId: context.read<SettingsCubit>().getSettings().token, context: context);
|
||||
context.read<SettingsCubit>().changeFcmToken(context.read<SettingsCubit>().getSettings().token);
|
||||
}
|
||||
} else {
|
||||
SettingsLocalDataRepository().setLocationCityKeys(null, null);
|
||||
}
|
||||
|
||||
if (appConfig.getWeatherMode() == "1") {
|
||||
getWeatherData();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getWeatherData() async {
|
||||
if (lat != null && lon != null) {
|
||||
context.read<WeatherCubit>().getWeatherDetails(langId: (Hive.box(settingsBoxKey).get(currentLanguageCodeKey)), lat: lat.toString(), lon: lon.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void getBreakingNews() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<BreakingNewsCubit>().getBreakingNews(langId: languageId);
|
||||
});
|
||||
}
|
||||
|
||||
void getGeneralNews() {
|
||||
context.read<GeneralNewsCubit>().getGeneralNews(langId: languageId, latitude: locationValue.first, longitude: locationValue.last);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
appConfig = context.read<AppConfigurationCubit>();
|
||||
authConfig = context.read<AuthCubit>();
|
||||
languageId = context.read<AppLocalizationCubit>().state.id;
|
||||
getSections();
|
||||
if (appConfig.getWeatherMode() == "1" || appConfig.getLocationWiseNewsMode() == "1") showPermissionPopup();
|
||||
if (authConfig.getUserId() != "0") {
|
||||
getUserData();
|
||||
}
|
||||
getLiveStreamData();
|
||||
if (appConfig.getBreakingNewsMode() == "1") getBreakingNews();
|
||||
if (appConfig.getMaintenanceMode() == "1") Navigator.of(context).pushReplacementNamed(Routes.maintenance);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
featuredSectionsScrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void hasMoreFeaturedSectionsScrollListener() {
|
||||
if (featuredSectionsScrollController.position.atEdge) {
|
||||
if (context.read<SectionCubit>().hasMoreSections()) {
|
||||
context.read<SectionCubit>().getMoreSections(langId: languageId, latitude: locationValue.first, longitude: locationValue.last);
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
|
||||
Widget breakingNewsMarquee() {
|
||||
return BlocBuilder<BreakingNewsCubit, BreakingNewsState>(builder: ((context, state) {
|
||||
return (state is BreakingNewsFetchSuccess && state.breakingNews.isNotEmpty)
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(top: 10),
|
||||
color: primaryColor,
|
||||
height: 32,
|
||||
child: Marqueer.builder(
|
||||
pps: 25.0,
|
||||
restartAfterInteractionDuration: const Duration(seconds: 1),
|
||||
separatorBuilder: (_, index) =>
|
||||
Center(child: Text(' ● ', style: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).secondary, fontWeight: FontWeight.normal))),
|
||||
itemBuilder: (context, index) {
|
||||
var multiplier = index ~/ state.breakingNews.length;
|
||||
var i = index;
|
||||
if (multiplier > 0) {
|
||||
i = index - (multiplier * state.breakingNews.length);
|
||||
}
|
||||
final item = state.breakingNews[i];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: CustomTextLabel(
|
||||
text: item.title!, textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).secondary, fontWeight: FontWeight.normal)));
|
||||
},
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
}));
|
||||
}
|
||||
|
||||
Widget getSectionList() {
|
||||
return BlocBuilder<GeneralNewsCubit, GeneralNewsState>(builder: (context, newsState) {
|
||||
return BlocBuilder<SectionCubit, SectionState>(builder: (context, sectionState) {
|
||||
if (sectionState is SectionFetchSuccess) {
|
||||
//if it has only one section and it doesn't have news in it then show No data found message
|
||||
if (sectionState.section.length == 1) {
|
||||
if (sectionState.section.first.newsType == "breaking_news") {
|
||||
if (sectionState.section.first.breakNewsTotal == 0) {
|
||||
return ErrorContainerWidget(errorMsg: ErrorMessageKeys.noDataMessage, onRetry: _refresh);
|
||||
}
|
||||
} else if (sectionState.section.first.newsTotal != null && sectionState.section.first.newsTotal! == 0) {
|
||||
return ErrorContainerWidget(errorMsg: ErrorMessageKeys.noDataMessage, onRetry: _refresh);
|
||||
}
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.zero,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: ((context, index) {
|
||||
FeatureSectionModel model = sectionState.section[index];
|
||||
//check for more featured sections
|
||||
if (index == sectionState.section.length - 1 && index != 0) {
|
||||
if (sectionState.hasMore) {
|
||||
if (sectionState.hasMoreFetchError) {
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return Center(child: Padding(padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 8.0), child: UiUtils.showCircularProgress(true, Theme.of(context).primaryColor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sectionData(model: model);
|
||||
}),
|
||||
itemCount: sectionState.section.length);
|
||||
}
|
||||
if (sectionState is SectionFetchFailure) {
|
||||
if (context.read<GeneralNewsCubit>().state is GeneralNewsFetchSuccess) {
|
||||
return sectionData(newsModelList: (context.read<GeneralNewsCubit>().state as GeneralNewsFetchSuccess).generalNews);
|
||||
} else {
|
||||
return ErrorContainerWidget(
|
||||
errorMsg: (sectionState.errorMessage.contains(ErrorMessageKeys.noInternet)) ? UiUtils.getTranslatedLabel(context, 'internetmsg') : sectionState.errorMessage, onRetry: _refresh);
|
||||
}
|
||||
}
|
||||
return sectionShimmer(context); //state is SectionFetchInProgress || state is SectionInitial
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Widget sectionData({FeatureSectionModel? model, List<NewsModel>? newsModelList}) {
|
||||
return (model != null)
|
||||
? Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
if (model.adSpaceDetails != null) AdSpaces(adsModel: model.adSpaceDetails!), //sponsored ads
|
||||
if (model.styleApp == 'style_1') Style1Section(model: model),
|
||||
if (model.styleApp == 'style_2') Style2Section(model: model),
|
||||
if (model.styleApp == 'style_3') Style3Section(model: model),
|
||||
if (model.styleApp == 'style_4') Style4Section(model: model),
|
||||
if (model.styleApp == 'style_5') Style5Section(model: model),
|
||||
if (model.styleApp == 'style_6') BlocProvider(create: (context) => SectionByIdCubit(SectionByIdRepository()), child: Style6Section(model: model))
|
||||
])
|
||||
: GeneralNewsRandomStyle(modelList: newsModelList!);
|
||||
}
|
||||
|
||||
//refresh function to refresh page
|
||||
Future<void> _refresh() async {
|
||||
getSections();
|
||||
getLocationPermission();
|
||||
if (authConfig.getUserId() != "0") {
|
||||
getUserData();
|
||||
getBookmark();
|
||||
getLikeNews();
|
||||
}
|
||||
getLiveStreamData();
|
||||
getPages();
|
||||
|
||||
if (appConfig.getBreakingNewsMode() == "1") getBreakingNews();
|
||||
if (appConfig.getMaintenanceMode() == "1") Navigator.of(context).pushReplacementNamed(Routes.maintenance);
|
||||
if (appConfig.getWeatherMode() == "1") getWeatherData();
|
||||
}
|
||||
|
||||
getPages() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<OtherPageCubit>().getOtherPage(langId: languageId);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: RefreshIndicator(
|
||||
key: _refreshIndicatorKey,
|
||||
onRefresh: () => _refresh(),
|
||||
child: BlocListener<GetUserByIdCubit, GetUserByIdState>(
|
||||
bloc: context.read<GetUserByIdCubit>(),
|
||||
listener: (context, state) {
|
||||
if (state is GetUserByIdFetchSuccess) {
|
||||
var data = state.result;
|
||||
if (data[STATUS] == 0) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'deactiveMsg'), context);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
UiUtils.userLogOut(contxt: context);
|
||||
});
|
||||
} else {
|
||||
authConfig.updateDetails(
|
||||
authModel: AuthModel(
|
||||
id: data[ID].toString(),
|
||||
name: data[NAME],
|
||||
status: data[STATUS].toString(),
|
||||
mobile: data[MOBILE],
|
||||
email: data[EMAIL],
|
||||
type: data[TYPE],
|
||||
profile: data[PROFILE],
|
||||
role: data[ROLE].toString(),
|
||||
jwtToken: data[TOKEN],
|
||||
isAuthor: data[IS_AUTHOR],
|
||||
authorDetails: (data[IS_AUTHOR] == 1 && data[AUTHOR] != null) ? Author.fromJson(data[AUTHOR]) : null));
|
||||
}
|
||||
}
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
controller: featuredSectionsScrollController,
|
||||
physics: ClampingScrollPhysics(), //To restrict scrolling on Refresh
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 15.0, end: 15.0, bottom: 10.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const LiveWithSearchView(),
|
||||
BlocBuilder<WeatherCubit, WeatherState>(builder: (context, state) {
|
||||
if (state is WeatherFetchSuccess) {
|
||||
return WeatherDataView(weatherData: state.weatherData);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
}),
|
||||
breakingNewsMarquee(),
|
||||
getSectionList()
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
))),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
|
||||
Widget commonSectionTitle(FeatureSectionModel model, BuildContext context) {
|
||||
return ListTile(
|
||||
minVerticalPadding: 5,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: CustomTextLabel(
|
||||
text: model.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.bold),
|
||||
softWrap: true,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
if ((model.newsType == 'news' || model.newsType == "user_choice") || model.videosType == 'news' && model.newsType != 'breaking_news') {
|
||||
Navigator.of(context).pushNamed(Routes.sectionNews, arguments: {"sectionId": model.id!, "title": model.title!});
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.sectionBreakNews, arguments: {"sectionId": model.id!, "title": model.title!});
|
||||
}
|
||||
},
|
||||
child: CustomTextLabel(
|
||||
text: 'viewMore',
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(decoration: TextDecoration.underline, fontWeight: FontWeight.bold, color: UiUtils.getColorScheme(context).outline)),
|
||||
)
|
||||
],
|
||||
),
|
||||
subtitle: (model.shortDescription != null)
|
||||
? CustomTextLabel(
|
||||
text: model.shortDescription!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6)),
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis)
|
||||
: SizedBox.shrink(),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/cubits/generalNewsCubit.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
|
||||
class GeneralNewsRandomStyle extends StatefulWidget {
|
||||
final List<NewsModel> modelList;
|
||||
|
||||
const GeneralNewsRandomStyle({super.key, required this.modelList});
|
||||
|
||||
@override
|
||||
GeneralNewsRandomStyleState createState() => GeneralNewsRandomStyleState();
|
||||
}
|
||||
|
||||
class GeneralNewsRandomStyleState extends State<GeneralNewsRandomStyle> {
|
||||
late final ScrollController scrollController = ScrollController()..addListener(hasMoreGeneralNewsListener);
|
||||
late int counter; //counter will handle unique index in both list & grid
|
||||
late List<NewsModel> newsList;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
newsList = widget.modelList;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void hasMoreGeneralNewsListener() {
|
||||
if (scrollController.position.maxScrollExtent == scrollController.offset) {
|
||||
if (context.read<GeneralNewsCubit>().hasMoreGeneralNews()) {
|
||||
context.read<GeneralNewsCubit>().getMoreGeneralNews(
|
||||
langId: context.read<AppLocalizationCubit>().state.id,
|
||||
latitude: SettingsLocalDataRepository().getLocationCityValues().first,
|
||||
longitude: SettingsLocalDataRepository().getLocationCityValues().last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
counter = 0;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListView.separated(
|
||||
controller: scrollController,
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.zero,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: newsList.length,
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return (index.isOdd && counter + 1 < newsList.length) ? getGrid() : const SizedBox.shrink();
|
||||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return (counter < newsList.length) ? listRow(counter++) : const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget getGrid() {
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
child: GridView.count(
|
||||
crossAxisCount: 1,
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: List.generate((counter % 3 == 0) ? 3 : 2, (index) {
|
||||
return Padding(padding: const EdgeInsets.only(right: 15), child: listRow((counter < newsList.length) ? counter++ : counter));
|
||||
})));
|
||||
}
|
||||
|
||||
Widget listRow(int index) {
|
||||
NewsModel newsModel = newsList[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 15),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
List<NewsModel> newList = [];
|
||||
newList.addAll(newsList);
|
||||
newList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsList[index], "newsList": newList, "isFromBreak": false, "fromShowMore": false});
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: ShaderMask(
|
||||
shaderCallback: (rect) =>
|
||||
LinearGradient(begin: Alignment.center, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
|
||||
blendMode: BlendMode.darken,
|
||||
child: Container(
|
||||
width: double.maxFinite,
|
||||
height: MediaQuery.of(context).size.height / 3.3,
|
||||
color: primaryColor.withValues(alpha: 0.15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: newsModel.image!,
|
||||
fit: BoxFit.cover,
|
||||
width: double.maxFinite,
|
||||
height: MediaQuery.of(context).size.height / 3.3,
|
||||
isVideo: newsModel.type == 'videos' ? true : false),
|
||||
))),
|
||||
if (newsModel.type == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.12,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> allNewsList = List.from(newsList)..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": newsModel, "otherVideos": allNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context))),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
bottom: 10,
|
||||
start: 10,
|
||||
end: 10,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (newsModel.categoryName != null)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||
child: CustomTextLabel(
|
||||
text: newsModel.categoryName!,
|
||||
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(color: secondaryColor.withOpacity(0.6)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: CustomTextLabel(
|
||||
text: newsModel.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.normal),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
],
|
||||
))
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
145
news-app/lib/ui/screens/HomePage/Widgets/LiveWithSearchView.dart
Normal file
145
news-app/lib/ui/screens/HomePage/Widgets/LiveWithSearchView.dart
Normal file
@@ -0,0 +1,145 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/svgPictureWidget.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/cubits/themeCubit.dart';
|
||||
import 'package:news/ui/styles/appTheme.dart';
|
||||
import 'package:news/cubits/liveStreamCubit.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
|
||||
class LiveWithSearchView extends StatefulWidget {
|
||||
const LiveWithSearchView({super.key});
|
||||
|
||||
@override
|
||||
LiveWithSearchState createState() => LiveWithSearchState();
|
||||
}
|
||||
|
||||
class LiveWithSearchState extends State<LiveWithSearchView> {
|
||||
Widget liveWithSearchView() {
|
||||
return BlocBuilder<LiveStreamCubit, LiveStreamState>(
|
||||
bloc: context.read<LiveStreamCubit>(),
|
||||
builder: (context, state) {
|
||||
if (state is LiveStreamFetchSuccess) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Logo Caribe
|
||||
Container(
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: Center(
|
||||
child: SvgPictureWidget(assetName: "logo_caribe", height: 40.0, width: 40.0),
|
||||
)),
|
||||
const SizedBox(width: 10),
|
||||
// Search bar
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30.0), color: UiUtils.getColorScheme(context).surface),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10.0),
|
||||
child: Icon(Icons.search_rounded, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10.0),
|
||||
child: CustomTextLabel(text: 'searchHomeNews', maxLines: 3, textStyle: TextStyle(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7)))),
|
||||
],
|
||||
),
|
||||
)),
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(Routes.search);
|
||||
},
|
||||
)),
|
||||
if (state.liveStream.isNotEmpty && context.read<AppConfigurationCubit>().getLiveStreamMode() == "1")
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10.0),
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: Center(
|
||||
child: SvgPictureWidget(assetName: (context.read<ThemeCubit>().state.appTheme == AppTheme.Dark ? "live_news_dark" : "live_news"), height: 30.0, width: 54.0),
|
||||
)),
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(Routes.live, arguments: {"liveNews": state.liveStream});
|
||||
},
|
||||
))
|
||||
],
|
||||
));
|
||||
}
|
||||
if (state is LiveStreamFetchFailure) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
// Logo Caribe
|
||||
Container(
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: Center(
|
||||
child: SvgPictureWidget(assetName: "logo_caribe", height: 40.0, width: 40.0),
|
||||
)),
|
||||
const SizedBox(width: 10),
|
||||
// Search bar
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30.0), color: UiUtils.getColorScheme(context).surface),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(padding: const EdgeInsetsDirectional.only(start: 10.0), child: Icon(Icons.search_rounded, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10.0),
|
||||
child: CustomTextLabel(text: 'searchHomeNews', maxLines: 3, textStyle: TextStyle(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(Routes.search);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return shimmerData(); //state is LiveStreamFetchInProgress || state is LiveStreamInitial
|
||||
});
|
||||
}
|
||||
|
||||
Widget shimmerData() {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey.withOpacity(0.6),
|
||||
highlightColor: Colors.grey,
|
||||
child: Container(
|
||||
height: 60,
|
||||
margin: const EdgeInsets.only(top: 15),
|
||||
width: double.maxFinite,
|
||||
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: Colors.grey.withOpacity(0.6))));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return liveWithSearchView();
|
||||
}
|
||||
}
|
||||
29
news-app/lib/ui/screens/HomePage/Widgets/SectionShimmer.dart
Normal file
29
news-app/lib/ui/screens/HomePage/Widgets/SectionShimmer.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
Widget sectionShimmer(BuildContext context) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey.withOpacity(0.6),
|
||||
highlightColor: Colors.grey,
|
||||
child: ListView(shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsetsDirectional.only(top: 10), children: [
|
||||
Container(
|
||||
height: 55,
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: Colors.grey.withOpacity(0.6), borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height / 3.3,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: const EdgeInsets.only(top: 15),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.grey.withOpacity(0.6)),
|
||||
);
|
||||
}),
|
||||
]));
|
||||
}
|
||||
321
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle1.dart
Normal file
321
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle1.dart
Normal file
@@ -0,0 +1,321 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/strings.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
|
||||
class Style1Section extends StatefulWidget {
|
||||
final FeatureSectionModel model;
|
||||
|
||||
const Style1Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Style1SectionState createState() => Style1SectionState();
|
||||
}
|
||||
|
||||
class Style1SectionState extends State<Style1Section> {
|
||||
int? style1Sel;
|
||||
PageController? _pageStyle1Controller = PageController();
|
||||
int limit = limitOfStyle1;
|
||||
int newsLength = 0;
|
||||
int brNewsLength = 0;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageStyle1Controller!.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
newsLength = (widget.model.newsType == 'news' || widget.model.newsType == "user_choice") ? widget.model.news!.length : widget.model.videos!.length;
|
||||
brNewsLength = widget.model.newsType == 'breaking_news' ? widget.model.breakNews!.length : widget.model.breakVideos!.length;
|
||||
|
||||
return style1Data(widget.model);
|
||||
}
|
||||
|
||||
Widget style1Data(FeatureSectionModel model) {
|
||||
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
commonSectionTitle(model, context),
|
||||
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
|
||||
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
|
||||
style1NewsData(model),
|
||||
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
|
||||
style1BreakNewsData(model)
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
Widget style1NewsData(FeatureSectionModel model) {
|
||||
if ((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length > 1 : model.videos!.length > 1) {
|
||||
style1Sel ??= 1;
|
||||
_pageStyle1Controller = PageController(initialPage: 1, viewportFraction: 0.87);
|
||||
} else {
|
||||
style1Sel = 0;
|
||||
_pageStyle1Controller = PageController(initialPage: 0, viewportFraction: 1);
|
||||
}
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.36,
|
||||
width: double.maxFinite,
|
||||
child: PageView.builder(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemCount: min(newsLength, limit),
|
||||
scrollDirection: Axis.horizontal,
|
||||
pageSnapping: true,
|
||||
controller: _pageStyle1Controller,
|
||||
onPageChanged: (index) {
|
||||
setState(() => style1Sel = index);
|
||||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
|
||||
return InkWell(
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.only(start: 7, end: 7, top: style1Sel == index ? 0 : MediaQuery.of(context).size.height * 0.027),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: style1Sel == index ? MediaQuery.of(context).size.height / 4 : MediaQuery.of(context).size.height / 5,
|
||||
width: double.maxFinite,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.075,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> newsList = List.from(model.videos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": newsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 8,
|
||||
end: 8,
|
||||
top: MediaQuery.of(context).size.height / 7,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height / 5,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: const EdgeInsetsDirectional.all(10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(13),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (data.categoryName != null)
|
||||
Container(
|
||||
height: 20.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: data.categoryName!,
|
||||
textAlign: TextAlign.center,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
style1Indicator(model, min(newsLength, limit))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget style1BreakNewsData(FeatureSectionModel model) {
|
||||
if (model.newsType == 'breaking_news' ? model.breakNews!.length > 1 : model.breakVideos!.length > 1) {
|
||||
style1Sel ??= 1;
|
||||
_pageStyle1Controller = PageController(initialPage: 1, viewportFraction: 0.87);
|
||||
} else {
|
||||
style1Sel = 0;
|
||||
_pageStyle1Controller = PageController(initialPage: 0, viewportFraction: 1);
|
||||
}
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.36,
|
||||
width: double.maxFinite,
|
||||
child: PageView.builder(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemCount: min(brNewsLength, limit),
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: _pageStyle1Controller,
|
||||
reverse: false,
|
||||
onPageChanged: (index) {
|
||||
setState(() => style1Sel = index);
|
||||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsetsDirectional.only(start: 7, end: 7, top: style1Sel == index ? 0 : MediaQuery.of(context).size.height * 0.027),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (model.newsType == 'breaking_news') {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: style1Sel == index ? MediaQuery.of(context).size.height / 4 : MediaQuery.of(context).size.height / 5,
|
||||
width: double.maxFinite,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.075,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<BreakingNewsModel> allBrNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": allBrNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 8,
|
||||
end: 8,
|
||||
top: MediaQuery.of(context).size.height / 7,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height / 5,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: const EdgeInsetsDirectional.all(10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(13),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
|
||||
softWrap: true,
|
||||
maxLines: 4,
|
||||
overflow: TextOverflow.ellipsis))),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
style1Indicator(model, min(brNewsLength, limit))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget style1Indicator(FeatureSectionModel model, int len) {
|
||||
return len <= 1
|
||||
? const SizedBox.shrink()
|
||||
: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: map<Widget>(
|
||||
(model.newsType == 'news' || model.newsType == "user_choice")
|
||||
? model.news!
|
||||
: (model.newsType == BREAKING_NEWS)
|
||||
? model.breakNews!
|
||||
: (model.newsType == 'videos' && (model.videosTotal! > 0 && model.videos!.isNotEmpty))
|
||||
? model.videos!
|
||||
: model.breakVideos!,
|
||||
(index, url) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 5.0, end: 5.0),
|
||||
child: Container(
|
||||
height: 14.0,
|
||||
width: 14.0,
|
||||
decoration: BoxDecoration(color: Colors.transparent, shape: BoxShape.circle, border: Border.all(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
child: style1Sel == index
|
||||
? Container(
|
||||
margin: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(color: Theme.of(context).primaryColor, shape: BoxShape.circle),
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
List<T> map<T>(List list, Function handler) {
|
||||
List<T> result = [];
|
||||
int mapLength = (widget.model.newsType == 'news' || widget.model.newsType == "user_choice") ? min(newsLength, limit) : min(brNewsLength, limit);
|
||||
for (var i = 0; i < mapLength; i++) {
|
||||
result.add(handler(i, list[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
170
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle2.dart
Normal file
170
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle2.dart
Normal file
@@ -0,0 +1,170 @@
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
|
||||
class Style2Section extends StatelessWidget {
|
||||
final FeatureSectionModel model;
|
||||
bool isNews = true;
|
||||
|
||||
Style2Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return style2Data(model, context);
|
||||
}
|
||||
|
||||
Widget style2Data(FeatureSectionModel model, BuildContext context) {
|
||||
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
|
||||
if (model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") {
|
||||
if ((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty) {
|
||||
isNews = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (model.newsType == 'breaking_news' || model.videosType == "breaking_news") {
|
||||
if (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty) {
|
||||
isNews = false;
|
||||
}
|
||||
}
|
||||
int limit = limitOfAllOtherStyle;
|
||||
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
|
||||
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
|
||||
|
||||
var totalCount = (isNews) ? min(newsLength, limit) : min(brNewsLength, limit);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
commonSectionTitle(model, context),
|
||||
ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: totalCount,
|
||||
itemBuilder: (context, index) => (isNews)
|
||||
? setStyle2(context: context, index: index, model: model, newsModel: (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index])
|
||||
: setStyle2(context: context, index: index, model: model, breakingNewsModel: (model.newsType == 'breaking_news') ? model.breakNews![index] : model.breakVideos![index])),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
Widget setStyle2({required BuildContext context, required int index, required FeatureSectionModel model, NewsModel? newsModel, BreakingNewsModel? breakingNewsModel}) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: index == 0 ? 0 : 15),
|
||||
child: Column(
|
||||
children: [
|
||||
if (context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
|
||||
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
|
||||
nativeAdsShow(context: context, index: index),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsModel, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
} else if (model.newsType == 'breaking_news') {
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": breakingNewsModel, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: ShaderMask(
|
||||
shaderCallback: (rect) =>
|
||||
LinearGradient(begin: Alignment.center, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
|
||||
blendMode: BlendMode.darken,
|
||||
child: Container(
|
||||
color: primaryColor.withAlpha(5),
|
||||
width: double.maxFinite,
|
||||
height: MediaQuery.of(context).size.height / 3.3,
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: (newsModel != null) ? newsModel.image! : breakingNewsModel!.image!,
|
||||
fit: BoxFit.cover,
|
||||
width: double.maxFinite,
|
||||
height: MediaQuery.of(context).size.height / 3.3,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
)),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.12,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> newsList = [];
|
||||
List<BreakingNewsModel> brNewsList = [];
|
||||
if (model.breakVideos != null && model.breakVideos!.isNotEmpty) brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
|
||||
if (model.videos != null && model.videos!.isNotEmpty) newsList = List.from(model.videos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {
|
||||
"from": 1,
|
||||
"model": (newsModel != null) ? newsModel : breakingNewsModel!,
|
||||
if (newsList.isNotEmpty) "otherVideos": newsList,
|
||||
if (brNewsList.isNotEmpty) "otherBreakingVideos": brNewsList
|
||||
});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context))),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
bottom: 10,
|
||||
start: 10,
|
||||
end: 10,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (newsModel != null && newsModel.categoryName != null)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||
child: CustomTextLabel(
|
||||
text: newsModel.categoryName!,
|
||||
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(color: secondaryColor.withOpacity(0.6)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: CustomTextLabel(
|
||||
text: (newsModel != null) ? newsModel.title! : breakingNewsModel!.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.normal),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
241
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle3.dart
Normal file
241
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle3.dart
Normal file
@@ -0,0 +1,241 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
|
||||
|
||||
class Style3Section extends StatelessWidget {
|
||||
final FeatureSectionModel model;
|
||||
|
||||
const Style3Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return style3Data(model, context);
|
||||
}
|
||||
|
||||
Widget style3Data(FeatureSectionModel model, BuildContext context) {
|
||||
int limit = limitOfAllOtherStyle;
|
||||
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
|
||||
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
|
||||
|
||||
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
commonSectionTitle(model, context),
|
||||
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.34,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: min(brNewsLength, limit),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if ((index != 0 && index % nativeAdsIndex == 0) &&
|
||||
context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
|
||||
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
|
||||
SizedBox(width: MediaQuery.of(context).size.width * 0.87, child: nativeAdsShow(context: context, index: index)),
|
||||
InkWell(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.87,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 0,
|
||||
end: 0,
|
||||
top: MediaQuery.of(context).size.height / 15,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height / 4,
|
||||
margin: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10, end: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 9),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
)),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 30,
|
||||
end: 30,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: MediaQuery.of(context).size.height / 4.7,
|
||||
width: double.maxFinite,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.085,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'breaking_news') {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
})),
|
||||
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
|
||||
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.34,
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: min(newsLength, limit),
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if ((index != 0 && index % nativeAdsIndex == 0) &&
|
||||
context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
|
||||
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
|
||||
SizedBox(width: MediaQuery.of(context).size.width * 0.87, child: nativeAdsShow(context: context, index: index)),
|
||||
InkWell(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.87,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 0,
|
||||
end: 0,
|
||||
top: MediaQuery.of(context).size.height / 15,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height / 3.8,
|
||||
margin: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10, end: 10, top: 10, bottom: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (data.categoryName != null)
|
||||
Container(
|
||||
height: 20.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: data.categoryName!,
|
||||
textAlign: TextAlign.center,
|
||||
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle:
|
||||
Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: 30,
|
||||
end: 30,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: MediaQuery.of(context).size.height / 4.7,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.085,
|
||||
start: MediaQuery.of(context).size.width / 3,
|
||||
end: MediaQuery.of(context).size.width / 3,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
})),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}
|
||||
189
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle4.dart
Normal file
189
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle4.dart
Normal file
@@ -0,0 +1,189 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
|
||||
class Style4Section extends StatelessWidget {
|
||||
final FeatureSectionModel model;
|
||||
|
||||
const Style4Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return style4Data(model, context);
|
||||
}
|
||||
|
||||
Widget style4Data(FeatureSectionModel model, BuildContext context) {
|
||||
int limit = limitOfAllOtherStyle;
|
||||
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
|
||||
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
|
||||
|
||||
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
commonSectionTitle(model, context),
|
||||
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
|
||||
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
|
||||
Column(
|
||||
children: [
|
||||
setGridLayout(
|
||||
context: context,
|
||||
totalCount: min(newsLength, limit),
|
||||
childWidget: (context, index) {
|
||||
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
|
||||
return InkWell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(7),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: UiUtils.getColorScheme(context).surface),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(children: [
|
||||
setNewsImage(context: context, imageURL: data.image!),
|
||||
if (data.categoryName != null && data.categoryName != "")
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
|
||||
height: 18.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: data.categoryName!,
|
||||
textAlign: TextAlign.center,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.065,
|
||||
start: MediaQuery.of(context).size.width / 6,
|
||||
end: MediaQuery.of(context).size.width / 6,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
]),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
//show interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
|
||||
setGridLayout(
|
||||
context: context,
|
||||
totalCount: min(brNewsLength, limit),
|
||||
childWidget: (context, index) {
|
||||
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
|
||||
return InkWell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(7),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: UiUtils.getColorScheme(context).surface),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(children: [
|
||||
setNewsImage(context: context, imageURL: data.image!),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.065,
|
||||
start: MediaQuery.of(context).size.width / 6,
|
||||
end: MediaQuery.of(context).size.width / 6,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context)),
|
||||
),
|
||||
]),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'breaking_news') {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
})
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
Widget setGridLayout({required BuildContext context, required int totalCount, required Widget? Function(BuildContext, int) childWidget}) {
|
||||
return GridView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(mainAxisExtent: MediaQuery.of(context).size.height * 0.27, crossAxisCount: 2, crossAxisSpacing: 10, mainAxisSpacing: 13),
|
||||
shrinkWrap: true,
|
||||
itemCount: totalCount,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: childWidget);
|
||||
}
|
||||
|
||||
Widget setNewsImage({required BuildContext context, required String imageURL}) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: imageURL,
|
||||
height: MediaQuery.of(context).size.height * 0.175,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false));
|
||||
}
|
||||
}
|
||||
400
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle5.dart
Normal file
400
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle5.dart
Normal file
@@ -0,0 +1,400 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
|
||||
class Style5Section extends StatelessWidget {
|
||||
final FeatureSectionModel model;
|
||||
|
||||
const Style5Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return style5Data(model, context);
|
||||
}
|
||||
|
||||
Widget style5SingleNewsData(FeatureSectionModel model, BuildContext context) {
|
||||
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![0] : model.videos![0];
|
||||
return InkWell(
|
||||
child: Container(
|
||||
height: MediaQuery.of(context).size.height * 0.28,
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!, height: MediaQuery.of(context).size.height * 0.28, width: double.maxFinite, fit: BoxFit.cover, isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (data.categoryName != null)
|
||||
Container(
|
||||
height: 20.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: data.categoryName!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.01),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.01),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.calendar_month, color: secondaryColor, size: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10),
|
||||
child: CustomTextLabel(
|
||||
text: UiUtils.convertToAgo(context, DateTime.parse(data.publishDate ?? data.date!), 0)!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w600),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
InkWell(
|
||||
child: Padding(padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02), child: UiUtils.setPlayButton(context: context)),
|
||||
onTap: () {
|
||||
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeWhere((item) => item.id == data.id);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(0);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget style5SingleBreakNewsData(FeatureSectionModel model, BuildContext context) {
|
||||
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![0] : model.breakVideos![0];
|
||||
return InkWell(
|
||||
child: Container(
|
||||
height: MediaQuery.of(context).size.height * 0.28,
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: ShaderMask(
|
||||
shaderCallback: (rect) => LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
|
||||
blendMode: BlendMode.darken,
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!, height: MediaQuery.of(context).size.height * 0.28, width: double.maxFinite, fit: BoxFit.cover, isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
),
|
||||
(model.newsType == 'videos')
|
||||
? Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
InkWell(
|
||||
child: Padding(padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02), child: UiUtils.setPlayButton(context: context)),
|
||||
onTap: () {
|
||||
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeWhere((item) => item.id == data.id);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
|
||||
},
|
||||
),
|
||||
],
|
||||
)),
|
||||
)
|
||||
: Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'breaking_news') {
|
||||
//show interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(0);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget style5Data(FeatureSectionModel model, BuildContext context) {
|
||||
int limit = limitOfAllOtherStyle;
|
||||
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
|
||||
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
|
||||
|
||||
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
commonSectionTitle(model, context),
|
||||
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") && (model.newsType == 'news' || model.newsType == "user_choice")
|
||||
? model.news!.isNotEmpty
|
||||
: model.videos!.isNotEmpty)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
style5SingleNewsData(model, context),
|
||||
if (newsLength > 1)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15.0),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: List.generate(min(newsLength, limit), (index) {
|
||||
if (newsLength > index + 1) {
|
||||
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index + 1] : model.videos![index + 1];
|
||||
return InkWell(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2.35,
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: MediaQuery.of(context).size.height * 0.15,
|
||||
width: MediaQuery.of(context).size.width / 2.35,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
if (data.categoryName != null)
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
|
||||
height: 18.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: data.categoryName!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.058,
|
||||
start: MediaQuery.of(context).size.width / 8.5,
|
||||
end: MediaQuery.of(context).size.width / 8.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context, heightVal: 28)),
|
||||
),
|
||||
]),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.labelMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.calendar_month, color: UiUtils.getColorScheme(context).primaryContainer, size: 15),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 5),
|
||||
child: CustomTextLabel(
|
||||
text: UiUtils.convertToAgo(context, DateTime.parse(data.publishDate ?? data.date!), 0)!,
|
||||
textAlign: TextAlign.left,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'news' || model.newsType == "user_choice") {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<NewsModel> newsList = [];
|
||||
newsList.addAll(model.news!);
|
||||
newsList.removeAt(index + 1);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
})),
|
||||
)),
|
||||
],
|
||||
),
|
||||
if ((model.newsType == 'breaking_news' && model.breakNews?.isNotEmpty == true) || (model.videosType == 'breaking_news' && model.breakVideos?.isNotEmpty == true))
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
style5SingleBreakNewsData(model, context),
|
||||
if (brNewsLength > 1)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15.0),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: List.generate(min(brNewsLength, limit), (index) {
|
||||
if (brNewsLength > index + 1) {
|
||||
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index + 1] : model.breakVideos![index + 1];
|
||||
return InkWell(
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width / 2.35,
|
||||
padding: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: data.image!,
|
||||
height: MediaQuery.of(context).size.height * 0.15,
|
||||
width: MediaQuery.of(context).size.width / 2.35,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: model.newsType == 'videos' ? true : false),
|
||||
),
|
||||
if (model.newsType == 'videos')
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.058,
|
||||
start: MediaQuery.of(context).size.width / 8.5,
|
||||
end: MediaQuery.of(context).size.width / 8.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
|
||||
},
|
||||
child: UiUtils.setPlayButton(context: context, heightVal: 28)),
|
||||
),
|
||||
]),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: CustomTextLabel(
|
||||
text: data.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (model.newsType == 'breaking_news') {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = [];
|
||||
breakList.addAll(model.breakNews!);
|
||||
breakList.removeAt(index + 1);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
})),
|
||||
)),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}
|
||||
216
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle6.dart
Normal file
216
news-app/lib/ui/screens/HomePage/Widgets/SectionStyle6.dart
Normal file
@@ -0,0 +1,216 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/cubits/sectionByIdCubit.dart';
|
||||
import 'package:news/data/models/BreakingNewsModel.dart';
|
||||
import 'package:news/data/models/FeatureSectionModel.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/networkImage.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
|
||||
class Style6Section extends StatefulWidget {
|
||||
final FeatureSectionModel model;
|
||||
|
||||
const Style6Section({super.key, required this.model});
|
||||
|
||||
@override
|
||||
Style6SectionState createState() => Style6SectionState();
|
||||
}
|
||||
|
||||
class Style6SectionState extends State<Style6Section> {
|
||||
int? style6Sel;
|
||||
bool isNews = true;
|
||||
late final ScrollController style6ScrollController = ScrollController()..addListener(hasMoreSectionScrollListener);
|
||||
late BreakingNewsModel breakingNewsData;
|
||||
late NewsModel newsData;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getSectionDataById();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
style6ScrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void hasMoreSectionScrollListener() {
|
||||
if (style6ScrollController.position.maxScrollExtent == style6ScrollController.offset) {
|
||||
if (context.read<SectionByIdCubit>().hasMoreSections() && !(context.read<SectionByIdCubit>().state is SectionByIdFetchInProgress)) {
|
||||
context.read<SectionByIdCubit>().getMoreSectionById(langId: context.read<AppLocalizationCubit>().state.id, sectionId: widget.model.id!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return style6Data();
|
||||
}
|
||||
|
||||
void getSectionDataById() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<SectionByIdCubit>().getSectionById(
|
||||
langId: context.read<AppLocalizationCubit>().state.id,
|
||||
sectionId: widget.model.id!,
|
||||
latitude: SettingsLocalDataRepository().getLocationCityValues().first,
|
||||
longitude: SettingsLocalDataRepository().getLocationCityValues().last);
|
||||
});
|
||||
}
|
||||
|
||||
Widget style6Data() {
|
||||
return BlocBuilder<SectionByIdCubit, SectionByIdState>(builder: (context, state) {
|
||||
if (state is SectionByIdFetchSuccess) {
|
||||
isNews = (state.type == 'news' || state.type == 'user_choice' || state.type == 'videos') && state.newsModel.isNotEmpty
|
||||
? true
|
||||
: (state.type == 'breaking_news' || state.type == 'videos') && state.breakNewsModel.isNotEmpty
|
||||
? false
|
||||
: isNews;
|
||||
int totalCount = (isNews) ? state.newsModel.length : state.breakNewsModel.length;
|
||||
return (state.breakNewsModel.isNotEmpty || state.newsModel.isNotEmpty)
|
||||
? Padding(padding: const EdgeInsets.symmetric(vertical: 5), child: style6NewsDetails(newsData: state.newsModel, brNewsData: state.breakNewsModel, total: totalCount, type: state.type))
|
||||
: SizedBox.shrink();
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
});
|
||||
}
|
||||
|
||||
Widget style6NewsDetails({List<NewsModel>? newsData, List<BreakingNewsModel>? brNewsData, String? type, int total = 0}) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 2.8,
|
||||
child: SingleChildScrollView(
|
||||
controller: style6ScrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: List.generate(total, (index) {
|
||||
return SizedBox(
|
||||
width: 180,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: (isNews)
|
||||
? setImageCard(index: index, total: total, type: type!, newsModel: newsData![index], allNewsList: newsData)
|
||||
: setImageCard(index: index, total: total, type: type!, breakingNewsModel: brNewsData![index], breakingNewsList: brNewsData)));
|
||||
}))));
|
||||
}
|
||||
|
||||
Widget setImageCard(
|
||||
{required int index,
|
||||
required int total,
|
||||
required String type,
|
||||
NewsModel? newsModel,
|
||||
BreakingNewsModel? breakingNewsModel,
|
||||
List<NewsModel>? allNewsList,
|
||||
List<BreakingNewsModel>? breakingNewsList}) {
|
||||
return InkWell(
|
||||
child: Stack(children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: ShaderMask(
|
||||
shaderCallback: (bounds) {
|
||||
return LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(bounds);
|
||||
},
|
||||
blendMode: BlendMode.darken,
|
||||
child: Container(
|
||||
color: primaryColor.withValues(alpha: 0.15),
|
||||
width: MediaQuery.of(context).size.width / 1.9,
|
||||
height: MediaQuery.of(context).size.height / 2.5,
|
||||
child: CustomNetworkImage(
|
||||
networkImageUrl: (newsModel != null) ? newsModel.image! : breakingNewsModel!.image!,
|
||||
height: MediaQuery.of(context).size.height / 2.5,
|
||||
width: MediaQuery.of(context).size.width / 1.9,
|
||||
fit: BoxFit.cover,
|
||||
isVideo: type == "videos"),
|
||||
),
|
||||
)),
|
||||
(newsModel != null && newsModel.categoryName != null)
|
||||
? Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
|
||||
height: 20.0,
|
||||
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: Theme.of(context).primaryColor),
|
||||
child: CustomTextLabel(
|
||||
text: newsModel.categoryName!,
|
||||
textAlign: TextAlign.center,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)))
|
||||
: const SizedBox.shrink(),
|
||||
(type == "videos")
|
||||
? Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
top: MediaQuery.of(context).size.height * 0.13,
|
||||
start: MediaQuery.of(context).size.width / 6,
|
||||
end: MediaQuery.of(context).size.width / 6,
|
||||
child: UiUtils.setPlayButton(context: context))
|
||||
: const SizedBox.shrink(),
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
bottom: 5,
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
(newsModel != null)
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: CustomTextLabel(
|
||||
text: UiUtils.convertToAgo(context, DateTime.parse(newsModel.publishDate ?? newsModel.date!), 3)!,
|
||||
textStyle: Theme.of(context).textTheme.labelSmall!.copyWith(color: Colors.white)))
|
||||
: const SizedBox.shrink(),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
width: MediaQuery.of(context).size.width * 0.50,
|
||||
child: CustomTextLabel(
|
||||
text: (newsModel != null) ? newsModel.title! : breakingNewsModel!.title!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: secondaryColor),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis))
|
||||
]),
|
||||
),
|
||||
]),
|
||||
onTap: () {
|
||||
if (type == "videos") {
|
||||
List<NewsModel> newsList = [];
|
||||
List<BreakingNewsModel> brNewsList = [];
|
||||
if (newsModel != null && allNewsList != null && allNewsList.isNotEmpty) {
|
||||
newsList = List.from(allNewsList);
|
||||
newsList.removeAt(index);
|
||||
} else if (breakingNewsModel != null && breakingNewsList != null && breakingNewsList.isNotEmpty) {
|
||||
brNewsList = List.from(breakingNewsList);
|
||||
brNewsList.removeAt(index);
|
||||
}
|
||||
// List<NewsModel> newsList = List.from(allNewsList ?? [])..removeAt(index);
|
||||
// List<BreakingNewsModel> breakNewsList = List.from(breakingNewsList ?? [])..removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {
|
||||
"from": (newsModel != null) ? 1 : 3,
|
||||
if (newsModel != null) "model": newsModel,
|
||||
if (breakingNewsModel != null) "breakModel": breakingNewsModel,
|
||||
"otherBreakingVideos": brNewsList,
|
||||
"otherVideos": newsList,
|
||||
});
|
||||
} else if (type == 'news' || type == "user_choice") {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
if (allNewsList != null && allNewsList.isNotEmpty) {
|
||||
List<NewsModel> newsList = List.from(allNewsList);
|
||||
newsList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsModel, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
|
||||
}
|
||||
} else {
|
||||
if (breakingNewsList != null && breakingNewsList.isNotEmpty) {
|
||||
//interstitial ads
|
||||
UiUtils.showInterstitialAds(context: context);
|
||||
List<BreakingNewsModel> breakList = List.from(breakingNewsList);
|
||||
breakList.removeAt(index);
|
||||
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": breakingNewsModel, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
140
news-app/lib/ui/screens/HomePage/Widgets/WeatherData.dart
Normal file
140
news-app/lib/ui/screens/HomePage/Widgets/WeatherData.dart
Normal file
@@ -0,0 +1,140 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:news/utils/hiveBoxKeys.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/data/models/WeatherData.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
|
||||
class WeatherDataView extends StatefulWidget {
|
||||
final WeatherDetails weatherData;
|
||||
|
||||
const WeatherDataView({super.key, required this.weatherData});
|
||||
|
||||
@override
|
||||
WeatherDataState createState() => WeatherDataState();
|
||||
}
|
||||
|
||||
class WeatherDataState extends State<WeatherDataView> {
|
||||
late Future<void> _future;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_future = UiUtils.checkIfValidLocale(langCode: Hive.box(settingsBoxKey).get(currentLanguageCodeKey));
|
||||
}
|
||||
|
||||
Widget weatherDataView() {
|
||||
return FutureBuilder<void>(
|
||||
future: _future,
|
||||
builder: (context, snapshot) {
|
||||
DateTime now = DateTime.now();
|
||||
String day = DateFormat('EEEE').format(now);
|
||||
WeatherDetails weatherData = widget.weatherData;
|
||||
return Container(
|
||||
margin: const EdgeInsetsDirectional.only(top: 15.0),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: UiUtils.getColorScheme(context).surface),
|
||||
height: MediaQuery.of(context).size.height * 0.14,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CustomTextLabel(
|
||||
text: 'weatherLbl',
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Image.network("https:${weatherData.icon!}", width: 40.0, height: 40.0),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 7.0),
|
||||
child: CustomTextLabel(
|
||||
text: "${weatherData.tempC!.toString()}\u2103",
|
||||
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 1))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
CustomTextLabel(
|
||||
text: "${weatherData.name!},${weatherData.region!}",
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w600),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 1),
|
||||
CustomTextLabel(
|
||||
text: weatherData.country!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w600),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 3.0),
|
||||
child: CustomTextLabel(
|
||||
text: day,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 1)),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 3.0),
|
||||
child: CustomTextLabel(
|
||||
text: weatherData.text!,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 3.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Icon(Icons.arrow_upward_outlined, size: 13.0, color: UiUtils.getColorScheme(context).primaryContainer),
|
||||
CustomTextLabel(
|
||||
text: "H:${weatherData.maxTempC!.toString()}\u2103",
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 8.0),
|
||||
child: Icon(Icons.arrow_downward_outlined, size: 13.0, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
CustomTextLabel(
|
||||
text: "L:${weatherData.minTempC!.toString()}\u2103",
|
||||
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true)
|
||||
],
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return weatherDataView();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user