parent
1b8299b8f8
commit
6127ec88db
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
@ -1,40 +1,194 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:daflmusic/mainPage/main_mainpage.dart';
|
import 'package:daflmusic/mainPage/main_mainpage.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:daflmusic/signInPage/main_signIn_page.dart';
|
import 'package:daflmusic/signInPage/main_signIn_page.dart';
|
||||||
import 'package:daflmusic/homePage/main_homepage.dart';
|
import 'package:daflmusic/homePage/main_homepage.dart';
|
||||||
import 'package:daflmusic/signUpPage/main_signUp_page.dart';
|
import 'package:daflmusic/signUpPage/main_signUp_page.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({super.key});
|
|
||||||
|
|
||||||
// This widget is the root of your application.
|
// This widget is the root of your application.
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context){
|
||||||
SystemChrome.setEnabledSystemUIMode(
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||||
SystemUiMode.immersiveSticky
|
return ChangeNotifierProvider(
|
||||||
);
|
create: (context) => CardProvider(),
|
||||||
return MaterialApp(
|
child: MaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'Flutter Demo',
|
title: 'Flutter Demo',
|
||||||
theme: ThemeData(
|
|
||||||
// This is the theme of your application.
|
|
||||||
//
|
|
||||||
// Try running your application with "flutter run". You'll see the
|
|
||||||
// application has a blue toolbar. Then, without quitting the app, try
|
|
||||||
// changing the primarySwatch below to Colors.green and then invoke
|
|
||||||
// "hot reload" (press "r" in the console where you ran "flutter run",
|
|
||||||
// or simply save your changes to "hot reload" in a Flutter IDE).
|
|
||||||
// Notice that the counter didn't reset back to zero; the application
|
|
||||||
// is not restarted.
|
|
||||||
primarySwatch: Colors.blue,
|
|
||||||
),
|
|
||||||
home: MainHomePage(),
|
home: MainHomePage(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CardStatus { like, disLike, discovery}
|
||||||
|
|
||||||
|
class CardProvider extends ChangeNotifier{
|
||||||
|
List<String> _urlImages = [];
|
||||||
|
bool _isDragging = false;
|
||||||
|
double _angle = 0;
|
||||||
|
Offset _position = Offset.zero;
|
||||||
|
Size _screenSize = Size.zero;
|
||||||
|
|
||||||
|
List<String> get urlImages => _urlImages;
|
||||||
|
bool get isDragging => _isDragging;
|
||||||
|
Offset get position => _position;
|
||||||
|
double get angle => _angle;
|
||||||
|
|
||||||
|
CardProvider() {
|
||||||
|
resetUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetUsers() {
|
||||||
|
_urlImages = <String>[
|
||||||
|
'https://khaligidilit.com/assets/images/cover-LAI%CC%88LA-Khali.jpeg',
|
||||||
|
'https://m.media-amazon.com/images/I/61aUOMzwS8L._SL1440_.jpg',
|
||||||
|
'https://pbs.twimg.com/media/ExJ-My-XMAE3Ko2.jpg',
|
||||||
|
'https://cdns-images.dzcdn.net/images/cover/2818a661c6d533155ce6dffc256b1f51/500x500.jpg',
|
||||||
|
'https://cdns-images.dzcdn.net/images/cover/b351f0e935c9c3901f8d893b92ab952a/500x500.jpg',
|
||||||
|
'https://cdns-images.dzcdn.net/images/cover/65147b581f2ace9e0f0723ee76e70fda/500x500.jpg',
|
||||||
|
'https://images.genius.com/a8b6d39d8b10d7441527e2f5cf6b6ca5.1000x1000x1.jpg',
|
||||||
|
'https://cdns-images.dzcdn.net/images/cover/17a9747927ac3e5ea56f92f635d9180c/500x500.jpg',
|
||||||
|
].reversed.toList();
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScreenSize(Size screenSize) => _screenSize = screenSize;
|
||||||
|
|
||||||
|
void startPosition(DragStartDetails details) {
|
||||||
|
_isDragging = true;
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePosition(DragUpdateDetails details) {
|
||||||
|
_position += details.delta;
|
||||||
|
|
||||||
|
final x = _position.dx;
|
||||||
|
_angle = 45 * x / _screenSize.width;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void endPosition() {
|
||||||
|
_isDragging = false;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final status = getStatus(force: true);
|
||||||
|
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case CardStatus.like:
|
||||||
|
like();
|
||||||
|
break;
|
||||||
|
case CardStatus.disLike:
|
||||||
|
dislike();
|
||||||
|
break;
|
||||||
|
case CardStatus.discovery:
|
||||||
|
discovery();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
resetPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void resetPosition() {
|
||||||
|
_isDragging = false;
|
||||||
|
_position = Offset.zero;
|
||||||
|
_angle = 0;
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
double getStatusOpacity() {
|
||||||
|
final delta = 100;
|
||||||
|
final pos = max(_position.dx.abs(), _position.dy.abs());
|
||||||
|
final opacity = pos / delta;
|
||||||
|
|
||||||
|
return min(opacity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardStatus? getStatus({bool force = false}) {
|
||||||
|
final x = _position.dx;
|
||||||
|
final y = _position.dy;
|
||||||
|
final forceDiscovery = x.abs() < 20;
|
||||||
|
|
||||||
|
if(force) {
|
||||||
|
final delta = 100;
|
||||||
|
|
||||||
|
if (x >= delta) {
|
||||||
|
return CardStatus.like;
|
||||||
|
} else if ( x <= -delta){
|
||||||
|
return CardStatus.disLike;
|
||||||
|
} else if ( y <= -delta / 2 && forceDiscovery){
|
||||||
|
return CardStatus.discovery;
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
final delta = 20;
|
||||||
|
|
||||||
|
if(y <= -delta * 2 && forceDiscovery) {
|
||||||
|
return CardStatus.discovery;
|
||||||
|
} else if ( x >= delta) {
|
||||||
|
return CardStatus.like;
|
||||||
|
} else if ( x <= -delta) {
|
||||||
|
return CardStatus.disLike;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void dislike() {
|
||||||
|
print("dislike");
|
||||||
|
_angle = -20;
|
||||||
|
_position -= Offset(2 * _screenSize.width, 0);
|
||||||
|
_nextCard();
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void discovery() {
|
||||||
|
print("discovery");
|
||||||
|
_angle = 0;
|
||||||
|
_position -= Offset(0, _screenSize.height);
|
||||||
|
_discovery_card();
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: 'Ajouté',
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: ToastGravity.TOP,
|
||||||
|
timeInSecForIosWeb: 2,
|
||||||
|
backgroundColor: Colors.deepPurple,
|
||||||
|
textColor: Colors.white
|
||||||
|
);
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void like() {
|
||||||
|
print("like");
|
||||||
|
_angle = 20;
|
||||||
|
_position += Offset(2 * _screenSize.width, 0);
|
||||||
|
_nextCard();
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _nextCard() async {
|
||||||
|
if ( _urlImages.isEmpty) return;
|
||||||
|
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
_urlImages.removeLast();
|
||||||
|
resetPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _discovery_card() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
|
resetPosition();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,159 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:daflmusic/dafl_card.dart';
|
||||||
|
import 'package:daflmusic/main.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
class User{
|
||||||
|
final String chanteur;
|
||||||
|
final String titre;
|
||||||
|
final String urlImage;
|
||||||
|
|
||||||
|
const User({
|
||||||
|
required this.chanteur,
|
||||||
|
required this.titre,
|
||||||
|
required this.urlImage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DaflCard extends StatefulWidget {
|
||||||
|
final String urlImage;
|
||||||
|
final bool isFront;
|
||||||
|
|
||||||
|
const DaflCard({
|
||||||
|
Key? key,
|
||||||
|
required this.urlImage,
|
||||||
|
required this.isFront,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DaflCard> createState() => _DaflCardState();
|
||||||
|
}
|
||||||
|
class _DaflCardState extends State<DaflCard>{
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
|
final provider = Provider.of<CardProvider>(context, listen: false);
|
||||||
|
provider.setScreenSize(size);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => SizedBox.expand(
|
||||||
|
child: widget.isFront ? buildFrontCard() : buildCard(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget buildCard() => ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: NetworkImage(widget.urlImage),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
alignment: Alignment(0,0),
|
||||||
|
),
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget buildStamps() {
|
||||||
|
final provider = Provider.of<CardProvider>(context);
|
||||||
|
final status = provider.getStatus();
|
||||||
|
final opacity = provider.getStatusOpacity();
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case CardStatus.like:
|
||||||
|
final child = buildStamp(image: 'assets/images/icon_like.png', opacity: opacity);
|
||||||
|
return child;
|
||||||
|
case CardStatus.disLike:
|
||||||
|
final child = buildStamp(image: 'assets/images/icon_dislike.png', opacity: opacity);
|
||||||
|
return child;
|
||||||
|
case CardStatus.discovery:
|
||||||
|
final child = buildStamp(image: 'assets/images/icon_discovery.png', opacity: opacity);
|
||||||
|
return child;
|
||||||
|
default:
|
||||||
|
return Container();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildStamp({
|
||||||
|
double angle = 0,
|
||||||
|
required String image,
|
||||||
|
required double opacity,
|
||||||
|
}) {
|
||||||
|
return Opacity(opacity: opacity,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.7),
|
||||||
|
border: Border.all(color: Color(0xFF3F1DC3), width: 6),
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20))
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Image.asset(
|
||||||
|
image,
|
||||||
|
width: 100,
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildFrontCard() => GestureDetector(
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
final provider = Provider.of<CardProvider>(context);
|
||||||
|
final position = provider.position;
|
||||||
|
final milliseconds = provider.isDragging ? 0 : 400;
|
||||||
|
|
||||||
|
final center = constraints.smallest.center(Offset.zero);
|
||||||
|
final angle = provider.angle * pi / 180;
|
||||||
|
final rotatedMatrix = Matrix4.identity()
|
||||||
|
..translate(center.dx, center.dy)
|
||||||
|
..rotateZ(angle)
|
||||||
|
..translate(-center.dx, -center.dy);
|
||||||
|
|
||||||
|
return AnimatedContainer(
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
duration: Duration(milliseconds: milliseconds),
|
||||||
|
transform: rotatedMatrix..translate(position.dx, position.dy),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
buildCard(),
|
||||||
|
buildStamps(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onPanStart: (details) {
|
||||||
|
final provider = Provider.of<CardProvider>(context, listen: false);
|
||||||
|
|
||||||
|
provider.startPosition(details);
|
||||||
|
},
|
||||||
|
onPanUpdate: (details) {
|
||||||
|
final provider = Provider.of<CardProvider>(context, listen: false);
|
||||||
|
|
||||||
|
provider.updatePosition(details);
|
||||||
|
},
|
||||||
|
onPanEnd: (details) {
|
||||||
|
final provider = Provider.of<CardProvider>(context, listen: false);
|
||||||
|
|
||||||
|
provider.endPosition();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in new issue