Commit 77e2c373 authored by m-spi's avatar m-spi

Refactor

parent d12c9d90
......@@ -4,55 +4,56 @@ import 'app_state.dart';
class FavoritePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
TindBookState state = Provider.of<TindBookState>(context);
@override
Widget build(BuildContext context) {
var appState = context.watch<TindBookState>();
var favorites = appState.favorites;
return Scaffold(
appBar: AppBar(
title: Text('Favorite Books'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.7,
),
itemCount: state.favorites.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageScreen(imagePath: state.getFav(index)['image']),
),
);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
state.getFav(index)['image'],
fit: BoxFit.cover,
),
),
);
},
),
);
}
}
class ImageScreen extends StatelessWidget {
final String imagePath;
const ImageScreen({Key? key, required this.imagePath}) : super(key: key);
return LayoutBuilder(builder: (context, constraints) {
return Scaffold(
backgroundColor: Colors.red[200],
body: favorites.length > 0 ? ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: favorites.length,
itemBuilder: (BuildContext context, int index){
return ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['title']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['subtitle']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['author']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['published']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['publisher']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['description']),
),
Container(
color: index%2 == 0 ? Colors.red[500] : Colors.red[400],
child: Text(favorites[index]['website']),
)
]
);
}
) : Text("No favorites yet !"),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Image.asset(imagePath),
),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'dart:math';
import 'app_state.dart';
import 'favorite_page.dart';
import 'swipe_page.dart';
void main() => runApp(const TindBook());
class TindBook extends StatelessWidget {
const TindBook({Key? key}) : super(key: key);
......@@ -133,287 +135,3 @@ class _MyHomePageState extends State<MyHomePage> {
);
}
}
class TindBookContent extends StatefulWidget {
const TindBookContent({Key? key}) : super(key: key);
@override
State<TindBookContent> createState() => _TindBookContentState();
}
class _TindBookContentState extends State<TindBookContent> {
late TindBookState state;
double _startX = 0.0;
double _currentX = 0.0;
double _deltaX = 0.0;
bool _isSwiping = false;
int currentImageIndex = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
state = Provider.of<TindBookState>(context);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
double containerWidth = constraints.maxWidth;
double containerHeight = constraints.maxHeight;
void handleSwipe(int direction) {
if (direction == 1) {
// Swipe right
if (currentImageIndex < state.data.length - 1) {
currentImageIndex++;
state.addIndexToFav(currentImageIndex);
}
} else {
// Swipe left
if (currentImageIndex > 0) {
currentImageIndex--;
}
}
}
return GestureDetector(
onHorizontalDragStart: (details) {
_startX = details.globalPosition.dx;
_isSwiping = true;
},
onHorizontalDragUpdate: (details) {
if (_isSwiping) {
_currentX = details.globalPosition.dx;
_deltaX = _currentX - _startX;
setState(() {});
}
},
onHorizontalDragEnd: (details) {
if (_isSwiping) {
_isSwiping = false;
print(state.data[currentImageIndex]['image']);
if (_deltaX > 50) {
handleSwipe(1);
showDialog(
context: context,
builder: (_) => SwipeFeedback(isSwipeRight: true),
);
} else if (_deltaX < -50) {
handleSwipe(-1);
showDialog(
context: context,
builder: (_) => SwipeFeedback(isSwipeRight: false),
);
}
}
_startX = 0.0;
_currentX = 0.0;
_deltaX = 0.0;
},
child: Stack(
children: [
Positioned.fill(child: Container(
color: Color.fromRGBO(250, 237, 205, 1),
height: containerHeight / 3,
width: containerWidth / 3,
)),
Positioned(
top: 20,
left: 20,
right: 20,
bottom: 20,
child: Transform.translate(
offset: Offset(_deltaX, 0.0),
child: Transform.rotate(
angle: _deltaX * 0.0002, // Adjust the rotation speed here
child: ClipRRect(
borderRadius: BorderRadius.circular(120), // Adjust the radius as needed
child: Image.asset(
state.data[currentImageIndex]['image'],
height: containerHeight / 3, // Adjust image height
width: containerWidth / 3, // Adjust image width
fit: BoxFit.contain,
),
),
),
),
),
Positioned(
top: 20,
left: 20,
right: 20,
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 10,
offset: Offset(0, 4),
)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Titre du livre ',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 5),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.all(8),
child: Text(
'un tres bon livre qui parle de beaucoup chose , notamment mais aussi de lorem ipsum dolor sit amet a m Doctrine est pas de ',
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
),
],
),
),
),
],
),
);
},
);
}
}
class SwipeFeedback extends StatefulWidget {
final bool isSwipeRight;
const SwipeFeedback({Key? key, required this.isSwipeRight}) : super(key: key);
@override
_SwipeFeedbackState createState() => _SwipeFeedbackState();
}
class _SwipeFeedbackState extends State<SwipeFeedback> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
late Timer _timer;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
);
_animation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(_controller);
_controller.forward();
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_timer = Timer(Duration(milliseconds: 200), () {
Navigator.of(context).pop(); // Dismiss the dialog after 500 milliseconds
});
} else if (status == AnimationStatus.dismissed) {
_controller.dispose();
}
});
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Opacity(
opacity: 1.0 - _animation.value,
child: Transform.scale(
scale: 1.0 + _animation.value * 0.5,
child: Icon(
widget.isSwipeRight ? Icons.favorite : Icons.close,
color: widget.isSwipeRight ? Colors.green : Colors.red,
size: 400.0,
),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
_timer.cancel(); // Cancel the timer when disposing the widget
super.dispose();
}
}
class FavoritePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
TindBookState state = Provider.of<TindBookState>(context);
return Scaffold(
appBar: AppBar(
title: Text('Favorite Books'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.7,
),
itemCount: state.favorites.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageScreen(imagePath: state.getFav(index)['image']),
),
);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
state.getFav(index)['image'],
fit: BoxFit.cover,
),
),
);
},
),
);
}
}
class ImageScreen extends StatelessWidget {
final String imagePath;
const ImageScreen({Key? key, required this.imagePath}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Image.asset(imagePath),
),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'app_state.dart';
class TindBookContent extends StatefulWidget {
const TindBookContent({Key? key}) : super(key: key);
@override
State<TindBookContent> createState() => _TindBookContentState();
}
class _TindBookContentState extends State<TindBookContent> {
late TindBookState state;
double _startX = 0.0;
double _currentX = 0.0;
double _deltaX = 0.0;
bool _isSwiping = false;
int currentImageIndex = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
state = Provider.of<TindBookState>(context);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
double containerWidth = constraints.maxWidth;
double containerHeight = constraints.maxHeight;
void handleSwipe(int direction) {
if (direction == 1) {
// Swipe right
if (currentImageIndex < state.data.length - 1) {
currentImageIndex++;
state.addIndexToFav(currentImageIndex);
}
} else {
// Swipe left
if (currentImageIndex > 0) {
currentImageIndex--;
}
}
}
return GestureDetector(
onHorizontalDragStart: (details) {
_startX = details.globalPosition.dx;
_isSwiping = true;
},
onHorizontalDragUpdate: (details) {
if (_isSwiping) {
_currentX = details.globalPosition.dx;
_deltaX = _currentX - _startX;
setState(() {});
}
},
onHorizontalDragEnd: (details) {
if (_isSwiping) {
_isSwiping = false;
print(state.data[currentImageIndex]['image']);
if (_deltaX > 50) {
handleSwipe(1);
showDialog(
context: context,
builder: (_) => SwipeFeedback(isSwipeRight: true),
);
} else if (_deltaX < -50) {
handleSwipe(-1);
showDialog(
context: context,
builder: (_) => SwipeFeedback(isSwipeRight: false),
);
}
}
_startX = 0.0;
_currentX = 0.0;
_deltaX = 0.0;
},
child: Stack(
children: [
Positioned.fill(child: Container(
color: Color.fromRGBO(250, 237, 205, 1),
height: containerHeight / 3,
width: containerWidth / 3,
)),
Positioned(
top: 20,
left: 20,
right: 20,
bottom: 20,
child: Transform.translate(
offset: Offset(_deltaX, 0.0),
child: Transform.rotate(
angle: _deltaX * 0.0002, // Adjust the rotation speed here
child: ClipRRect(
borderRadius: BorderRadius.circular(120), // Adjust the radius as needed
child: Image.asset(
state.data[currentImageIndex]['image'],
height: containerHeight / 3, // Adjust image height
width: containerWidth / 3, // Adjust image width
fit: BoxFit.contain,
),
),
),
),
),
Positioned(
top: 20,
left: 20,
right: 20,
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 10,
offset: Offset(0, 4),
)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Titre du livre ',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 5),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.all(8),
child: Text(
'un tres bon livre qui parle de beaucoup chose , notamment mais aussi de lorem ipsum dolor sit amet a m Doctrine est pas de ',
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
),
],
),
),
),
],
),
);
},
);
}
}
class SwipeFeedback extends StatefulWidget {
final bool isSwipeRight;
const SwipeFeedback({Key? key, required this.isSwipeRight}) : super(key: key);
@override
_SwipeFeedbackState createState() => _SwipeFeedbackState();
}
class _SwipeFeedbackState extends State<SwipeFeedback> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
late Timer _timer;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
);
_animation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(_controller);
_controller.forward();
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_timer = Timer(Duration(milliseconds: 200), () {
Navigator.of(context).pop(); // Dismiss the dialog after 500 milliseconds
});
} else if (status == AnimationStatus.dismissed) {
_controller.dispose();
}
});
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Opacity(
opacity: 1.0 - _animation.value,
child: Transform.scale(
scale: 1.0 + _animation.value * 0.5,
child: Icon(
widget.isSwipeRight ? Icons.favorite : Icons.close,
color: widget.isSwipeRight ? Colors.green : Colors.red,
size: 400.0,
),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
_timer.cancel(); // Cancel the timer when disposing the widget
super.dispose();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment