mirror of
https://github.com/ErfanRht/MovieLab.git
synced 2026-03-13 10:23:24 +08:00
add: poster page
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.speech.RecognitionService" />
|
||||
|
||||
@@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:movielab/constants/colors.dart';
|
||||
import 'package:movielab/models/show_models/full_show_model.dart';
|
||||
import 'package:movielab/modules/tools/navigate.dart';
|
||||
import 'package:movielab/pages/show/show_page/sections/posters.dart';
|
||||
import '../../../../widgets/buttons/glassmorphism_button.dart';
|
||||
import '../../../../widgets/section_title.dart';
|
||||
|
||||
@@ -25,11 +23,11 @@ class ShowPageMedia extends StatelessWidget {
|
||||
GmButton(
|
||||
text: "Posters",
|
||||
onTap: () {
|
||||
Navigate.pushTo(
|
||||
context,
|
||||
ShowPagePosters(
|
||||
posters: posters,
|
||||
));
|
||||
// Navigate.pushTo(
|
||||
// context,
|
||||
// ShowPagePosters(
|
||||
// posters: posters,
|
||||
// ));
|
||||
},
|
||||
color: kImdbColor,
|
||||
icon: FontAwesomeIcons.blog),
|
||||
|
||||
@@ -6,9 +6,11 @@ import 'package:movielab/constants/colors.dart';
|
||||
import 'package:movielab/constants/types.dart';
|
||||
import 'package:movielab/modules/cache/get_show_info.dart';
|
||||
import 'package:movielab/modules/preferences/preferences_shareholder.dart';
|
||||
import 'package:movielab/modules/tools/navigate.dart';
|
||||
import 'package:movielab/modules/tools/system_ui_overlay_style.dart';
|
||||
import 'package:movielab/pages/shared/show_popup/watchtime/watchtime.dart';
|
||||
import 'package:movielab/widgets/error.dart';
|
||||
import 'package:movielab/widgets/full_image_page.dart';
|
||||
import 'sections/bottom_bar/bottom_bar.dart';
|
||||
import 'sections/bottom_bar/sections/external_sites/external_sites.dart';
|
||||
import 'sections/index.dart';
|
||||
@@ -154,36 +156,48 @@ class _ShowPageState extends State<ShowPage> with TickerProviderStateMixin {
|
||||
child: Stack(
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
ShaderMask(
|
||||
shaderCallback: (rect) {
|
||||
// ignore: prefer_const_constructors
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: const [Colors.black, Colors.transparent],
|
||||
).createShader(Rect.fromLTRB(
|
||||
100, 250, rect.width, rect.height));
|
||||
},
|
||||
blendMode: BlendMode.dstIn,
|
||||
child: Hero(
|
||||
tag: "${widget.preTag}_show_${show.id}",
|
||||
child: CachedNetworkImage(
|
||||
fit: BoxFit.cover,
|
||||
height:
|
||||
MediaQuery.of(context).size.height * (2 / 3) -
|
||||
35,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
imageUrl: show.image,
|
||||
errorWidget: (context, url, error) =>
|
||||
const Icon(Icons.error),
|
||||
placeholder: (context, url) => const Center(
|
||||
child: SpinKitThreeBounce(
|
||||
color: Colors.white,
|
||||
size: 30.0,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigate.pushHeroicTo(
|
||||
context,
|
||||
FullImagePage(
|
||||
tag: "${widget.preTag}_show_${show.id}",
|
||||
imageUrl: show.image));
|
||||
},
|
||||
child: ShaderMask(
|
||||
shaderCallback: (rect) {
|
||||
// ignore: prefer_const_constructors
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: const [
|
||||
Colors.black,
|
||||
Colors.transparent
|
||||
],
|
||||
).createShader(Rect.fromLTRB(
|
||||
100, 250, rect.width, rect.height));
|
||||
},
|
||||
blendMode: BlendMode.dstIn,
|
||||
child: Hero(
|
||||
tag: "${widget.preTag}_show_${show.id}",
|
||||
child: CachedNetworkImage(
|
||||
fit: BoxFit.cover,
|
||||
height: MediaQuery.of(context).size.height *
|
||||
(2 / 3) -
|
||||
35,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
imageUrl: show.image,
|
||||
errorWidget: (context, url, error) =>
|
||||
const Icon(Icons.error),
|
||||
placeholder: (context, url) => const Center(
|
||||
child: SpinKitThreeBounce(
|
||||
color: Colors.white,
|
||||
size: 30.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15),
|
||||
child: Column(
|
||||
|
||||
192
lib/widgets/full_image_page.dart
Normal file
192
lib/widgets/full_image_page.dart
Normal file
@@ -0,0 +1,192 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:external_path/external_path.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:gallery_saver/gallery_saver.dart';
|
||||
import 'package:movielab/constants/colors.dart';
|
||||
import 'package:movielab/widgets/toast.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
class FullImagePage extends StatefulWidget {
|
||||
const FullImagePage({Key? key, required this.imageUrl, this.tag})
|
||||
: super(key: key);
|
||||
final String? tag;
|
||||
final String imageUrl;
|
||||
|
||||
@override
|
||||
State<FullImagePage> createState() => _FullImagePageState();
|
||||
}
|
||||
|
||||
class _FullImagePageState extends State<FullImagePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
Hero(
|
||||
tag: widget.tag!,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: widget.imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
String path = await ExternalPath
|
||||
.getExternalStoragePublicDirectory(
|
||||
ExternalPath.DIRECTORY_PICTURES);
|
||||
String imageName = widget.imageUrl.replaceFirst(
|
||||
"https://m.media-amazon.com/images/M/", "");
|
||||
try {
|
||||
await Share.shareFiles(
|
||||
['$path/MovieLab/$imageName'],
|
||||
);
|
||||
} catch (e) {
|
||||
// ignore: use_build_context_synchronously
|
||||
await downloadImage(context,
|
||||
imageUrl: widget.imageUrl);
|
||||
await Share.shareFiles(
|
||||
['$path/MovieLab/$imageName']);
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.share_rounded,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
await downloadImage(context,
|
||||
imageUrl: widget.imageUrl);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.download_rounded,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
downloadImage(BuildContext context, {required final String imageUrl}) async {
|
||||
try {
|
||||
LoadingUtils(context).startLoading();
|
||||
await GallerySaver.saveImage(
|
||||
imageUrl,
|
||||
albumName: "MovieLab",
|
||||
).then((value) => {
|
||||
LoadingUtils(context).stopLoading(),
|
||||
LoadingUtils(context).showResult(value ?? true)
|
||||
});
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print("Error: $e");
|
||||
}
|
||||
LoadingUtils(context).stopLoading();
|
||||
LoadingUtils(context).showResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
class LoadingUtils {
|
||||
late BuildContext context;
|
||||
|
||||
LoadingUtils(this.context);
|
||||
|
||||
// this is where you would do your fullscreen loading
|
||||
Future<void> startLoading() async {
|
||||
return await showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return const SimpleDialog(
|
||||
elevation: 0.0,
|
||||
backgroundColor:
|
||||
Colors.transparent, // can change this to your prefered color
|
||||
children: <Widget>[
|
||||
Center(
|
||||
child: SpinKitSpinningLines(
|
||||
color: Colors.white,
|
||||
size: 100,
|
||||
))
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> stopLoading() async {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
Future<void> showResult(final bool result) async {
|
||||
FToast fToast = FToast();
|
||||
fToast.init(context);
|
||||
fToast.removeQueuedCustomToasts();
|
||||
fToast.showToast(
|
||||
child: ToastWidget(
|
||||
mainText: result
|
||||
? "Image downloaded successfully"
|
||||
: "Error while downloading",
|
||||
buttonText: "Ok",
|
||||
buttonColor: kAccentColor,
|
||||
buttonOnTap: () async {
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
fToast.removeCustomToast();
|
||||
},
|
||||
),
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
toastDuration: const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
14
pubspec.lock
14
pubspec.lock
@@ -218,6 +218,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
external_path:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: external_path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -352,6 +359,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
gallery_saver:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: gallery_saver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
get:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -42,6 +42,8 @@ dependencies:
|
||||
share_plus: ^4.0.10
|
||||
image_picker: ^0.8.5+3
|
||||
flutter_cache_manager: ^3.3.0
|
||||
gallery_saver: ^2.3.2
|
||||
external_path: ^1.0.1
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user