From 15ad3afa2e0a13559d1ccaa36f5fd47d674024fe Mon Sep 17 00:00:00 2001
From: Sol Mendiola <57235692+SolMendiola@users.noreply.github.com>
Date: Wed, 25 Jan 2023 11:25:32 -0300
Subject: [PATCH] feat: Added new screen of videos (#74)
* Added new screen of videos
* Resolve comments
---
android/app/src/main/AndroidManifest.xml | 6 ++++
assets/images/1.5x/ic_youtube_logo.png | Bin 0 -> 567 bytes
assets/images/2.0x/ic_youtube_logo.png | Bin 0 -> 701 bytes
assets/images/3.0x/ic_youtube_logo.png | Bin 0 -> 930 bytes
assets/images/4.0x/ic_youtube_logo.png | Bin 0 -> 1242 bytes
assets/images/ic_youtube_logo.png | Bin 0 -> 417 bytes
ios/Runner/Info.plist | 4 +++
lib/core/common/config.dart | 4 ++-
lib/gen/assets.gen.dart | 5 ++++
lib/l10n/intl_en.arb | 4 ++-
lib/ui/common/app_base_button.dart | 15 +++++++++-
lib/ui/common/app_primary_button.dart | 3 ++
lib/ui/helper/launch_helper.dart | 27 +++++++++++++++++
lib/ui/videos/videos.dart | 35 +++++++++++++++++------
14 files changed, 92 insertions(+), 11 deletions(-)
create mode 100644 assets/images/1.5x/ic_youtube_logo.png
create mode 100644 assets/images/2.0x/ic_youtube_logo.png
create mode 100644 assets/images/3.0x/ic_youtube_logo.png
create mode 100644 assets/images/4.0x/ic_youtube_logo.png
create mode 100644 assets/images/ic_youtube_logo.png
create mode 100644 lib/ui/helper/launch_helper.dart
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 34e0766..d261653 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -34,9 +34,15 @@
+
+
+ 329
+
+
+
\ No newline at end of file
diff --git a/assets/images/1.5x/ic_youtube_logo.png b/assets/images/1.5x/ic_youtube_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..96ff2e3d73654dd2e8d47255dd959f3659773ae0
GIT binary patch
literal 567
zcmV-70?7S|P)X1^@s6RQmj^00009a7bBm000o2
z000o20Vd5lGynhq0drDELIAGL9O(c600d`2O+f$vv5yPg5U{`fjPJnuna)XK$MJ(DQ^a!m)QFo*_$c_bxhq0TK
zmIY8Z!hDN3jy&@7j6E3>)(GpZrVgl~fEs}#2F3DOT12ZsL=iDZ_y!rDtcI8Gj8r;_
z1{NykNj4vh*KNo?>#aBps4s6#{2k+L@9i3sQEEEMJUoanG{g7(VcAjPS*z(m#HX0L
zonJhny@{|8QNs#hMhu@2pPNRJLJeEOL@6plPS~*(B9fx5t+nnl_#Rb2$~r=A+1LpYdoD=rW+PA^c!7I6mu=9tq!BTQK
z!q(XQCj#m*bA#XpmqOrxWY#D+ZTDTnunrXw3B{d>bmJ{-B^hF9*HQ_*tVdX50gp(v
zmzY*5MHBdhX=;Tqu~#9o(e3;ydp1QZkKqHxs4SvwX3cWkcn~wrG1xt7f@Q
zu#RQ-)KFX-ifct_5aS2FTqja2bCvy;gQiNh!!i>8kPk{-tUNFFI@kaJ002ovPDHLk
FV1gp7_8!Ms2#wMpuRyz*HiKY$=FVHo+QbV80gYBD7t0TUm^
z9G*bliyypJxhHTe-%r3iXU;>Fa=iHUHLQPwsyBOs@ktI$Hu?EBC_2b|mfcP-mTfD8
zz5e)IdU=EvBA&mt9=h!9R77^>3srA*dG2mRC<_`S}yu*B)j%?|D#C)tPTJF
z(46Crnu}Y2Eg;!^tfb};V@HrEyHifLgO*{YP-VzM>6zm}qPw*~vU7
j6`N}X6)tYC9tpxffq?Xcrz=GM00000NkvXXu0mjf1rIwT
literal 0
HcmV?d00001
diff --git a/assets/images/3.0x/ic_youtube_logo.png b/assets/images/3.0x/ic_youtube_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..a577dd303b70a9938294378dbe5bb18eb6376560
GIT binary patch
literal 930
zcmV;T16}-yP)!o}kpOqiFnoirMa)Wnp6RKi4wVopG`M3B9}
zOmd85bVkA$mxstX#GK6Aq@3TMtfR|y3{Av(*f!3_=djVlO2<+@KkfE02Q=%8c(v0)
zM9-zzl8a7nasdI-V^EKBbC8{OkIQ~AEySbk^_cjrlv-Foti|LxZ(_nyt_aas+j?P$
z-re!LKM&$M+2-Knuvb)E2(j8ppQlGsIL&<)NWOro!3|dN78(_y{v4g
zjG8k5ZzyGI*;`zN*p8bPK8m~+8#;&(ek?)+f9XCYBg(1~A(j;>EW;D|Nq654co=+u
zz)1mFf!F#n6~2A-4%!41lgtN$B|27UN|oExOo
zyTLTlYn&+}^760@d6Ajq@t}+fZ&uki;;wy_54eY#qq3~8&}>#3M})xO$6-&Qx35E7
zbnyo{j~M1hFg~NEFwBJzQ2Yrsg>txg(Q&sPuXT>(u!S1oaxP^W(3Zzjb;N3SI5$xb
zWSLL9#M2Q`Q80hL{GtbIza_wGW5KZ^C}Vcb_ltDo>4@~0drDELIAGL9O(c600d`2O+f$vv5yPmAK^qz9qD$ojbr%KFZt9#Mxk2O;1UW(7O{@Y1>KoL(
z0gJ?L76qd03}g`oC>jNx;p-cI$P!IEicCQ>?ECdfTvIx
z*~ueVsFazV@SqdjWn?hvvL@*EH?}M3T=n6z)!
zbX4?M>1>mLeufUf_Fx3I%!7H5L>~^f`HR2TG{@!=WFiMfH}-ij+d&}3BaYZD*X-adlvXzyb|CP6Ah6$+WxL4NH@o`52wN;J
zbcKwAS7^`)c$NYOODZ4>x|7Xl84|^d+Pf4jNreX|yQaKVC)P#S
z0CyVptNlq{1Oo1Yrxmn@Nk-A6q)hhe>9P3q3sd9ZYw#=%;ZF9~-q{E?D0yW7<<-x#
z5Q#c^GMGLwn>xi_tk$mF0Wb0*Budk_^^?JwX2;1m`|PV<1nG6~b}=6WkJZ0#@4?@{
z9@n3`cqrHmeg`n%3*e97nSppFh)2s3lOn60onOat{^Fn?hrNuj7XaNhi#vEaB<@Of
z{QID?FsPY^&x?cdjhXsqoXk_1_41P$EPfbBcYOl)K76*CcO@!g`{g*SZ4T|TbYNx#Ie|vf15yk%};Q#;t07*qoM6N<$
Ef}#ddhyVZp
literal 0
HcmV?d00001
diff --git a/assets/images/ic_youtube_logo.png b/assets/images/ic_youtube_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d077b481da486880dac9c2a1ec975df141b31416
GIT binary patch
literal 417
zcmV;S0bc%zP)TBw(qzAfy%3_A8T**X3KN3d2;>z5
zP-AhODy?$(*gR;(Cw;QFMqmt~4)8V+k;kq8!;JrbV!p5*k7-g2Ae}DeNNA-Qmm
zOX@rv{?4UmCo3H-(F61BlW~@upMF7l6uE^!1*`qGLl?a-4kHB<%MN2B*l}6nW$4L@
zdm=9@SvSS4uT5EM3(cBI^7f7uRgZ0<`(CuVLLWJ*>btCHZT
+ LSApplicationQueriesSchemes
+
+ youtube
+
CADisableMinimumFrameDurationOnPhone
CFBundleDevelopmentRegion
diff --git a/lib/core/common/config.dart b/lib/core/common/config.dart
index b4ede7c..cdf29de 100644
--- a/lib/core/common/config.dart
+++ b/lib/core/common/config.dart
@@ -42,8 +42,10 @@ abstract class Config {
static Uri imagesTipsRepository =
Uri.parse('https://www.github.com/vandadnp/flutter-tips-and-tricks');
+ static String widgetOfTheWeekPlaylistId =
+ 'PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG';
static Uri widgetOfTheWeekLink = Uri.parse(
- 'https://www.youtube.com/watch?v=b6Z885Z46cU&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG',
+ 'https://www.youtube.com/playlist?list=$widgetOfTheWeekPlaylistId',
);
static String fluttipsRepository = 'https://github.com/xmartlabs/fluttips';
static Uri xmartlabsLinkedln =
diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart
index 8854d1f..69c4b5c 100644
--- a/lib/gen/assets.gen.dart
+++ b/lib/gen/assets.gen.dart
@@ -32,6 +32,10 @@ class $AssetsImagesGen {
AssetGenImage get icTwitterLogo =>
const AssetGenImage('assets/images/ic_twitter_logo.png');
+ /// File path: assets/images/ic_youtube_logo.png
+ AssetGenImage get icYoutubeLogo =>
+ const AssetGenImage('assets/images/ic_youtube_logo.png');
+
/// File path: assets/images/onboarding_branding.png
AssetGenImage get onboardingBranding =>
const AssetGenImage('assets/images/onboarding_branding.png');
@@ -59,6 +63,7 @@ class $AssetsImagesGen {
icInstagramLogo,
icLinkedlnLogo,
icTwitterLogo,
+ icYoutubeLogo,
onboardingBranding,
onboardingDescribeApp,
onboardingFavourite,
diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb
index adc3433..bffe969 100644
--- a/lib/l10n/intl_en.arb
+++ b/lib/l10n/intl_en.arb
@@ -64,6 +64,8 @@
"password": "Password",
"search": "Search",
"secondMessageEmptyFavoritesScreen": "2. Tap on the start icon on the bottom right of the screen",
- "videos": "Coming soon",
+ "videos": "Videos",
+ "videos_button": "Watch videos",
+ "videos_description": "Here you have series of quick, animated videos, each of which covers a particular widget from the Flutter SDK.\n\nWe’re working to improve this feature :)",
"xmartlabs_projects": "Xmartlabs' projects"
}
\ No newline at end of file
diff --git a/lib/ui/common/app_base_button.dart b/lib/ui/common/app_base_button.dart
index 1d31ca1..58f64d5 100644
--- a/lib/ui/common/app_base_button.dart
+++ b/lib/ui/common/app_base_button.dart
@@ -8,12 +8,14 @@ class AppBaseButton extends StatelessWidget {
final VoidCallback action;
final Color backgroundColor;
final Color textColor;
+ final Image? image;
const AppBaseButton({
required this.text,
required this.action,
required this.backgroundColor,
required this.textColor,
+ this.image,
Key? key,
}) : super(key: key);
@@ -29,6 +31,17 @@ class AppBaseButton extends StatelessWidget {
color: backgroundColor,
textColor: textColor,
onPressed: action,
- child: Text(text),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ if (image != null)
+ Container(
+ padding: EdgeInsets.only(right: 10.w),
+ child: image,
+ ),
+ Text(text),
+ ],
+ ),
);
}
diff --git a/lib/ui/common/app_primary_button.dart b/lib/ui/common/app_primary_button.dart
index 6d6b6c9..a012bbf 100644
--- a/lib/ui/common/app_primary_button.dart
+++ b/lib/ui/common/app_primary_button.dart
@@ -6,10 +6,12 @@ import 'package:fluttips/ui/theme/app_theme.dart';
class AppPrimaryButton extends StatelessWidget {
final String text;
final VoidCallback action;
+ final Image? image;
const AppPrimaryButton({
required this.text,
required this.action,
+ this.image,
Key? key,
}) : super(key: key);
@@ -17,6 +19,7 @@ class AppPrimaryButton extends StatelessWidget {
Widget build(BuildContext context) => AppBaseButton(
text: text,
action: action,
+ image: image,
backgroundColor: context.theme.colors.primary.shade100,
textColor: context.theme.colors.primary,
);
diff --git a/lib/ui/helper/launch_helper.dart b/lib/ui/helper/launch_helper.dart
new file mode 100644
index 0000000..ab6aa3f
--- /dev/null
+++ b/lib/ui/helper/launch_helper.dart
@@ -0,0 +1,27 @@
+import 'dart:io';
+import 'package:url_launcher/url_launcher.dart';
+
+Future openYoutubePlaylist(String playlistId) async {
+ final url = 'www.youtube.com/playlist?list=$playlistId';
+ final youtubeWebUri = Uri.parse('https://$url');
+ if (Platform.isIOS) {
+ if (await canLaunchUrl(Uri.parse('youtube://$url'))) {
+ await launchUrl(
+ Uri.parse('youtube://$url'),
+ mode: LaunchMode.externalApplication,
+ );
+ } else {
+ if (await canLaunchUrl(youtubeWebUri)) {
+ await launchUrl(youtubeWebUri);
+ } else {
+ throw Exception('Could not launch https://$url');
+ }
+ }
+ } else {
+ if (await canLaunchUrl(youtubeWebUri)) {
+ await launchUrl(youtubeWebUri);
+ } else {
+ throw Exception('Could not launch https://$url');
+ }
+ }
+}
diff --git a/lib/ui/videos/videos.dart b/lib/ui/videos/videos.dart
index e523724..4c28ac1 100644
--- a/lib/ui/videos/videos.dart
+++ b/lib/ui/videos/videos.dart
@@ -1,7 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:fluttips/ui/common/app_primary_button.dart';
import 'package:fluttips/ui/common/context_extensions.dart';
+import 'package:fluttips/ui/helper/launch_helper.dart';
import 'package:fluttips/ui/theme/app_theme.dart';
+import 'package:fluttips/gen/assets.gen.dart';
+import 'package:fluttips/core/common/config.dart';
class VideosScreen extends StatelessWidget {
const VideosScreen({Key? key}) : super(key: key);
@@ -12,21 +16,36 @@ class VideosScreen extends StatelessWidget {
class _VideosContentScreen extends StatelessWidget {
@override
- Widget build(BuildContext context) => Center(
+ Widget build(BuildContext context) => Container(
+ padding: EdgeInsets.fromLTRB(70.w, 30.h, 70.w, 30.h),
+ margin: EdgeInsets.only(right: 30.w, left: 20.w),
child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.localizations.videos,
- style: context.theme.textStyles.titleLarge!.copyWith(
- color: context.theme.colors.surface.shade700,
+ style: context.theme.textStyles.headlineLarge!.copyWith(
+ color: context.theme.colors.surface,
fontWeight: FontWeight.bold,
),
+ textDirection: TextDirection.ltr,
),
- SizedBox(height: 10.h),
- Icon(
- Icons.play_circle_outline_outlined,
- color: context.theme.colors.surface.shade700,
+ SizedBox(height: 20.h),
+ Text(
+ context.localizations.videos_description,
+ style: context.theme.textStyles.bodyLarge!.copyWith(
+ color: context.theme.colors.surface,
+ ),
+ textDirection: TextDirection.ltr,
+ ),
+ SizedBox(height: 20.h),
+ Divider(color: context.theme.colors.surface.shade700),
+ SizedBox(height: 30.h),
+ AppPrimaryButton(
+ image: Assets.images.icYoutubeLogo.image(),
+ text: context.localizations.videos_button,
+ action: () =>
+ openYoutubePlaylist(Config.widgetOfTheWeekPlaylistId),
),
],
),