-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: implemented the presentation layer of the news feed feature …
…and connected th UI with the providers
- Loading branch information
Showing
29 changed files
with
932 additions
and
93 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
const String kBaseAssetsPath = "assets"; | ||
const String kPlaceHolderImagePath = "$kBaseAssetsPath/placeholder.jpg"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import 'dart:ui'; | ||
|
||
const String kDarkPurpleHexCode = "#121421"; | ||
const String kDarkPurpleLighterHexCode = "#262B3F"; | ||
const String kPurpleHexCode = "#8800FF"; | ||
const String kPinkAccent30OpacityHexCode = "#801C41"; | ||
const String kPinkAccentHexCode = "#FF0066"; | ||
const String kPurpleAccentHexCode = "#FF00FF"; | ||
const String kTurquoiseHexCode = "#00FFCB"; | ||
const String kOrangeHexCode = "#FF7700"; | ||
const String kGreyHexCode = "#CBCBCB"; | ||
const String lightGreyHexCode = "#54596C"; | ||
|
||
//usage: ColorExtension.fromHex(purpleHexCode); | ||
|
||
extension ColorExtension on Color { | ||
static Color fromHex(String hexCode) { | ||
hexCode = hexCode.replaceAll("#", ""); | ||
if (hexCode.length == 6) { | ||
hexCode = "ff$hexCode"; //8 character long -> ff = opacity %100 | ||
} | ||
|
||
return Color(int.parse(hexCode, radix: 16)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
const String kNewsFeedString = "News Feed"; | ||
const String kServerFailureString = "Server Failure"; | ||
const String kConnectivityFailureString = "Connectivity Failure"; | ||
const String kUnknownString = "Unknown"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const double kLeftRightPaddingFactor = 0.06; | ||
const double kNewsItemLayoutMarginFactor = 0.025; | ||
const double kRadius = 20; | ||
const double kPaddingSmall = 2; | ||
const double kDefaultHeightFactor = 0.25; | ||
const double kSliverAppBarHeightFactor = 0.35; | ||
const double kSliverBackgroundHeightFactor = 0.40; | ||
const double kFooterHeightFactor = 0.10; | ||
const double kBackArrowSizeFactor = 0.08; | ||
const double kNewsItemTopMarginFactor = 0.02; | ||
const double kNewsItemBottomMarginFactor = 0.01; | ||
const double kNewsItemWidthFactor = 0.85; | ||
const double kNewsItemHeightFactor = kDefaultHeightFactor / 2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:news_app/core/presentation/resources/color_manager.dart'; | ||
import 'package:news_app/core/presentation/widgets/project_text_widgets.dart'; | ||
|
||
class AppIcon extends StatelessWidget { | ||
const AppIcon({Key? key}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Stack( | ||
alignment: Alignment.center, | ||
children: [ | ||
Icon( | ||
Icons.circle, | ||
color: ColorExtension.fromHex(kPurpleHexCode), | ||
), | ||
PlayFairDisplayText( | ||
text: "N", | ||
fontSize: 10, | ||
), | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
import 'package:news_app/core/presentation/resources/color_manager.dart'; | ||
import 'package:news_app/core/presentation/resources/values_manager.dart'; | ||
import 'package:news_app/core/presentation/widgets/project_text_widgets.dart'; | ||
import 'package:news_app/core/utilities/string_extension.dart'; | ||
import 'package:news_app/features/news_feed/presentation/providers/chosen_category_provider.dart'; | ||
|
||
class CategoryChip extends ConsumerWidget { | ||
const CategoryChip({ | ||
super.key, | ||
}); | ||
|
||
@override | ||
Widget build(BuildContext context, WidgetRef ref) { | ||
return DecoratedBox( | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.circular(kRadius), | ||
color: ColorExtension.fromHex(kPinkAccent30OpacityHexCode), | ||
), | ||
child: Center( | ||
child: Padding( | ||
padding: const EdgeInsets.all(kPaddingSmall), | ||
child: RobotoBoldText( | ||
text: ref.watch(chosenCategoryProvider).capitalize(), | ||
fontSize: 12, | ||
color: ColorExtension.fromHex(kPinkAccentHexCode), | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
lib/core/presentation/widgets/gradient_shadow_container.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:news_app/core/presentation/resources/values_manager.dart'; | ||
|
||
class GradientShadowContainer extends StatelessWidget { | ||
const GradientShadowContainer({Key? key, this.height, required this.child}) | ||
: super(key: key); | ||
|
||
final double? height; | ||
final Widget child; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Container( | ||
width: MediaQuery.sizeOf(context).width, | ||
height: | ||
height ?? MediaQuery.sizeOf(context).height * kDefaultHeightFactor, | ||
decoration: BoxDecoration( | ||
gradient: buildGradient(), | ||
), | ||
child: child, | ||
); | ||
} | ||
|
||
LinearGradient buildGradient() { | ||
return const LinearGradient( | ||
begin: Alignment.topCenter, | ||
end: Alignment.bottomCenter, | ||
stops: [ | ||
0.1, | ||
0.6, | ||
], | ||
colors: [Colors.transparent, Colors.black54], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:news_app/core/presentation/resources/color_manager.dart'; | ||
import 'package:news_app/core/presentation/resources/values_manager.dart'; | ||
import 'package:news_app/core/presentation/widgets/news_summary_big_widget.dart'; | ||
import 'package:news_app/features/news_feed/domain/entities/news_feed_entity.dart'; | ||
|
||
class NewsItemLayout extends StatelessWidget { | ||
const NewsItemLayout({Key? key, required this.articlesEntity}) | ||
: super(key: key); | ||
|
||
final ArticlesEntity articlesEntity; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Card( | ||
shape: RoundedRectangleBorder( | ||
borderRadius: BorderRadius.circular(kRadius), | ||
), | ||
color: ColorExtension.fromHex(kDarkPurpleLighterHexCode), | ||
margin: buildMargin(context), | ||
child: SizedBox( | ||
width: MediaQuery.sizeOf(context).width * kNewsItemWidthFactor, | ||
height: MediaQuery.sizeOf(context).height * kNewsItemHeightFactor, | ||
child: NewsSummaryBigWidget( | ||
articlesEntity: articlesEntity, | ||
), | ||
), | ||
); | ||
} | ||
|
||
EdgeInsets buildMargin(BuildContext context) { | ||
return EdgeInsets.only( | ||
top: MediaQuery.sizeOf(context).height * kNewsItemTopMarginFactor, | ||
left: MediaQuery.sizeOf(context).width * kLeftRightPaddingFactor, | ||
right: MediaQuery.sizeOf(context).width * kLeftRightPaddingFactor, | ||
bottom: MediaQuery.sizeOf(context).height * kNewsItemBottomMarginFactor, | ||
); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
lib/core/presentation/widgets/news_summary_big_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
import 'package:news_app/core/presentation/resources/color_manager.dart'; | ||
import 'package:news_app/core/presentation/resources/values_manager.dart'; | ||
import 'package:news_app/core/presentation/widgets/news_summary_small_widget.dart'; | ||
import 'package:news_app/core/presentation/widgets/project_fade_in_image.dart'; | ||
import 'package:news_app/core/presentation/widgets/project_text_widgets.dart'; | ||
import 'package:news_app/core/utilities/string_extension.dart'; | ||
import 'package:news_app/features/news_feed/domain/entities/news_feed_entity.dart'; | ||
import 'package:news_app/features/news_feed/presentation/providers/chosen_category_provider.dart'; | ||
|
||
class NewsSummaryBigWidget extends StatelessWidget { | ||
const NewsSummaryBigWidget({Key? key, required this.articlesEntity}) | ||
: super(key: key); | ||
|
||
final ArticlesEntity articlesEntity; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Row( | ||
children: [ | ||
Expanded( | ||
child: buildNewsImage(context), | ||
), | ||
Expanded( | ||
flex: 2, | ||
child: Column( | ||
children: [ | ||
Expanded( | ||
child: Align( | ||
alignment: Alignment.centerLeft, | ||
child: buildCategoryTitle(), | ||
), | ||
), | ||
Expanded( | ||
flex: 3, | ||
child: buildSmallNewsSummary(), | ||
), | ||
], | ||
), | ||
), | ||
buildEmptySpace(context), | ||
], | ||
); | ||
} | ||
|
||
Container buildNewsImage(BuildContext context) { | ||
return Container( | ||
margin: EdgeInsets.all( | ||
MediaQuery.sizeOf(context).width * kNewsItemLayoutMarginFactor, | ||
), | ||
decoration: BoxDecoration( | ||
color: ColorExtension.fromHex(lightGreyHexCode), | ||
borderRadius: BorderRadius.circular(kRadius), | ||
), | ||
child: Center( | ||
child: ClipRRect( | ||
borderRadius: BorderRadius.circular(kRadius), | ||
child: ProjectFadeInImage( | ||
networkImageURL: articlesEntity.urlToImage, | ||
), | ||
), | ||
), | ||
); | ||
} | ||
|
||
Consumer buildCategoryTitle() { | ||
return Consumer(builder: (context, ref, child) { | ||
return RobotoBoldText( | ||
text: ref.watch(chosenCategoryProvider).capitalize(), | ||
fontSize: 12, | ||
color: ColorExtension.fromHex(kTurquoiseHexCode), | ||
); | ||
}); | ||
} | ||
|
||
NewsSummarySmallWidget buildSmallNewsSummary() { | ||
return NewsSummarySmallWidget( | ||
articlesEntity: articlesEntity, | ||
isCategoryIncluded: false, | ||
titleFontSize: 14, | ||
); | ||
} | ||
|
||
SizedBox buildEmptySpace(BuildContext context) { | ||
return SizedBox( | ||
width: MediaQuery.sizeOf(context).width * kNewsItemLayoutMarginFactor * 2, | ||
); | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
lib/core/presentation/widgets/news_summary_small_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:news_app/core/presentation/widgets/category_chip.dart'; | ||
import 'package:news_app/core/presentation/widgets/project_text_widgets.dart'; | ||
import 'package:news_app/core/presentation/widgets/publish_time_widget.dart'; | ||
import 'package:news_app/core/presentation/widgets/source_info_widget.dart'; | ||
import 'package:news_app/features/news_feed/domain/entities/news_feed_entity.dart'; | ||
|
||
class NewsSummarySmallWidget extends StatelessWidget { | ||
const NewsSummarySmallWidget({ | ||
super.key, | ||
required this.articlesEntity, | ||
required this.isCategoryIncluded, | ||
this.titleFontSize, | ||
}); | ||
|
||
final ArticlesEntity articlesEntity; | ||
final bool isCategoryIncluded; | ||
final double? titleFontSize; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
children: [ | ||
Expanded( | ||
flex: 2, | ||
child: Align( | ||
alignment: Alignment.centerLeft, | ||
child: buildTitle(), | ||
), | ||
), | ||
const Spacer(), | ||
Expanded(child: buildSubtitle()), | ||
const Spacer() | ||
], | ||
); | ||
} | ||
|
||
Wrap buildTitle() { | ||
return Wrap( | ||
children: [ | ||
PlayFairDisplayText( | ||
fontSize: titleFontSize ?? 18, | ||
text: articlesEntity.title ?? "", | ||
maxLines: 2, | ||
) | ||
], | ||
); | ||
} | ||
|
||
Widget buildSubtitle() { | ||
return Wrap( | ||
children: [ | ||
Row( | ||
children: [ | ||
Expanded( | ||
flex: 4, | ||
child: SourceInfoWidget( | ||
source: articlesEntity.source?.name, | ||
), | ||
), | ||
const Spacer(), | ||
Expanded( | ||
flex: 4, | ||
child: PublishTimeWidget( | ||
timeAgo: articlesEntity.timeAgo, | ||
), | ||
), | ||
const Spacer( | ||
flex: 2, | ||
), | ||
if (isCategoryIncluded) | ||
const Expanded( | ||
flex: 4, | ||
child: CategoryChip(), | ||
) | ||
else | ||
const SizedBox.shrink(), | ||
], | ||
), | ||
], | ||
); | ||
} | ||
} |
Oops, something went wrong.