elCaribe app - customization and branding

This commit is contained in:
2025-12-12 19:09:42 -04:00
parent 9e5d0d8ebf
commit ba7deac9f3
402 changed files with 31833 additions and 0 deletions

View File

@@ -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)),
],
))
],
)),
);
}
}