|
- import 'dart:async';
- import 'dart:io';
- import 'dart:math';
- import 'package:chat/data/UserData.dart';
- import 'package:chat/data/WebData.dart';
- import 'package:chat/data/constants.dart';
- import 'package:chat/generated/i18n.dart';
- import 'package:chat/home/VipPage.dart';
- import 'package:chat/models/money_change.dart';
- import 'package:chat/utils/CustomUI.dart';
- import 'package:chat/utils/HttpUtil.dart';
- import 'package:chat/utils/MessageMgr.dart';
- import 'package:chat/utils/TokenMgr.dart';
- import 'package:chat/utils/flutter_windowmanager.dart';
- import 'package:chat/utils/screen.dart';
- import 'package:dio/dio.dart';
- import 'package:extended_image/extended_image.dart';
- import 'dart:ui' as ui;
- import 'package:flutter/material.dart';
- import 'package:flutter/rendering.dart';
- import 'package:provider/provider.dart';
- import 'ChargeMoney.dart';
-
- double initScale({Size imageSize, Size size, double initialScale}) {
- var n1 = imageSize.height / imageSize.width;
- var n2 = size.height / size.width;
- if (n1 > n2) {
- final FittedSizes fittedSizes =
- applyBoxFit(BoxFit.contain, imageSize, size);
- //final Size sourceSize = fittedSizes.source;
- Size destinationSize = fittedSizes.destination;
- return size.width / destinationSize.width;
- } else if (n1 / n2 < 1 / 4) {
- final FittedSizes fittedSizes =
- applyBoxFit(BoxFit.contain, imageSize, size);
- //final Size sourceSize = fittedSizes.source;
- Size destinationSize = fittedSizes.destination;
- return size.height / destinationSize.height;
- }
-
- return initialScale;
- }
-
- class PicSwiper extends StatefulWidget {
- final int id;
- final List<PicSwiperItem> pics;
- PicSwiper({this.id, this.pics});
- @override
- _PicSwiperState createState() => _PicSwiperState();
- }
-
- class _PicSwiperState extends State<PicSwiper>
- with SingleTickerProviderStateMixin {
- var rebuildIndex = StreamController<int>.broadcast();
- var rebuildSwiper = StreamController<bool>.broadcast();
- AnimationController _animationController;
- Animation<double> _animation;
- Function animationListener;
-
- // CancellationToken _cancelToken;
- // CancellationToken get cancelToken {
- // if (_cancelToken == null || _cancelToken.isCanceled)
- // _cancelToken = CancellationToken();
- //
- // return _cancelToken;
- // }
- List<double> doubleTapScales = <double>[1.0, 2.0];
- GlobalKey<ExtendedImageSlidePageState> slidePagekey =
- GlobalKey<ExtendedImageSlidePageState>();
- int currentIndex;
- bool _showSwiper = true;
- int _seconds = 0;
- bool isMyself = false;
- @override
- void initState() {
- setDisableScreenshots();
- for (int i = 0; i < widget.pics.length; i++) {
- if (widget.id == widget.pics[i].id) {
- currentIndex = i;
- break;
- }
- }
- isMyself = widget.pics[0].userId == UserData().basicInfo.userId;
- _animationController = AnimationController(
- duration: const Duration(milliseconds: 150), vsync: this);
-
- super.initState();
- }
-
- setDisableScreenshots() async {
- print('Platform.isAndroid ${Platform.isAndroid}');
- if (Platform.isAndroid) {
- await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
- }
- }
-
- clearFalgs() async {
- if (Platform.isAndroid) {
- await FlutterWindowManager.clearFlags(FlutterWindowManager.FLAG_SECURE);
- }
- }
-
- @override
- void dispose() {
- rebuildIndex.close();
- rebuildSwiper.close();
- _animationController?.dispose();
- clearGestureDetailsCache();
- clearFalgs();
- //cancelToken?.cancel();
- super.dispose();
- }
-
- void browsePhoto(id, userId, type, callback, {price = 0}) async {
- if (Provider.of<MoneyChangeProvider>(context).money < price) {
- CustomUI.buildOneConfirm(context, I18n.of(context).balance_insufficien,
- I18n.of(context).recharge, () {
- Navigator.of(context).pop();
- ChargeMoney.showChargeSheet(context, () {
- setState(() {});
- });
- });
- return;
- }
- var data = {
- "visitUserId": UserData().basicInfo.userId,
- "userId": userId,
- "pId": id,
- 'type': type,
- };
- data['sign'] = TokenMgr().getSign(data);
- data['price'] = price;
- Response res = await HttpUtil().post('user/browse/photo', data: data);
- Map resData = res.data;
- print(resData);
- if (resData['code'] == 0) {
- MessageMgr().emit('refresh_photo', id);
- callback();
- }
- }
-
- @override
- Widget build(BuildContext context) {
- var size = MediaQuery.of(context).size;
- bool isAgree = (widget.pics[currentIndex].type == PhotoType.destroy.index ||
- widget.pics[currentIndex].type == PhotoType.destroyMoney.index);
- var id = widget.pics[currentIndex].id;
- Widget result = Scaffold(
- // StreamBuilder(
- // builder: (BuildContext context, data) {},
- // initialData: true,
- // stream: rebuildSwiper.stream,
- // ),
- appBar: AppBar(
- backgroundColor: AppColors.NewAppbarBgColor,
- title: StreamBuilder<int>(
- builder: (BuildContext context, data) {
- return Text(
- '${data.data + 1} / ${widget.pics.length}',
- style: TextStyle(
- fontSize: 16, color: AppColors.NewAppbarTextColor),
- textScaleFactor: 1.0,
- );
- },
- initialData: currentIndex,
- stream: rebuildIndex.stream,
- ),
- leading: CustomUI.buildCustomLeading(context),
- centerTitle: true,
- elevation: 1,
- actions: <Widget>[
- isMyself
- ? InkWell(
- onTap: () {
- CustomUI.buildOneConfirm(
- context,
- I18n.of(context).sure_delete,
- I18n.of(context).determine, () {
- var id = widget.pics[currentIndex].id;
- HttpUtil().setPhote(context, id, 2, () {
- widget.pics.removeAt(currentIndex);
- MessageMgr().emit('refresh_photo', id);
- if (widget.pics.length == 0) {
- Navigator.of(context).pop();
- } else {
- setState(() {
- if (currentIndex != 0) currentIndex--;
- });
- }
- });
- Navigator.of(context).pop();
- });
- },
- child: Container(
- margin: EdgeInsets.only(right: 10),
- child: CircleAvatar(
- backgroundColor: Constants.GreyBackgroundColor,
- radius: 13.75,
- child: Icon(
- Icons.delete,
- color: Constants.BlackTextColor,
- size: 20,
- ))),
- )
- : Container()
- ],
- ),
- backgroundColor: Colors.black,
-
- /// if you use ExtendedImageSlidePage and slideType =SlideType.onlyImage,
- /// make sure your page is transparent background
- // color: Colors.white,
- // shadowColor: Colors.transparent,
- bottomNavigationBar: isMyself
- ? Container(
- decoration: BoxDecoration(
- color: Colors.white,
- border: Border(top: Constants.GreyBorderSide)),
- height: 40,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: <Widget>[
- Checkbox(
- value: isAgree,
- activeColor: Colors.blue,
- onChanged: (bool val) {
- HttpUtil().setPhote(context, id, isAgree ? 0 : 1, () {
- this.setState(() {
- isAgree = !isAgree;
- //如果是红包照片焚阅照片则变成红包照片
- //如果是普通焚阅照片则变成普通照片
- MessageMgr().emit('refresh_photo');
- if (isAgree) {
- if (widget.pics[currentIndex].type ==
- PhotoType.free.index) {
- widget.pics[currentIndex].type =
- PhotoType.destroy.index;
- }
- if (widget.pics[currentIndex].type ==
- PhotoType.money.index) {
- widget.pics[currentIndex].type =
- PhotoType.destroyMoney.index;
- }
- } else {
- if (widget.pics[currentIndex].type ==
- PhotoType.destroy.index) {
- widget.pics[currentIndex].type =
- PhotoType.free.index;
- }
- if (widget.pics[currentIndex].type ==
- PhotoType.destroyMoney.index) {
- widget.pics[currentIndex].type =
- PhotoType.money.index;
- }
- }
- });
- });
- },
- ),
- fixedText(I18n.of(context).destroy_after)
- ],
- ),
- )
- : Container(
- height: 0,
- ),
- body: Stack(
- //fit: StackFit.expand,
- children: <Widget>[
- ExtendedImageGesturePageView.builder(
- itemBuilder: (BuildContext context, int index) {
- var item = widget.pics[index];
- var picUrl = item.picUrl;
- var file = item.file;
- var _timer;
-
- bool isShow = _seconds != 0;
-
- _cancelTimer() {
- item.isWatch = true;
- _seconds = 0;
- _timer?.cancel();
- }
-
- _startTimer() {
- if (UserData().isMan()) {
- _seconds =
- UserData().isSuperVip ? 6 : (UserData().isVip ? 4 : 2);
- } else {
- _seconds = UserData().basicInfo.isAttestation ? 6 : 2;
- }
-
- _timer =
- new Timer.periodic(new Duration(seconds: 1), (timer) {
- _seconds--;
-
- setState(() {});
- if (_seconds <= 0) {
- _cancelTimer();
- }
- });
- }
-
- Widget image;
- if (file != null) {
- image = ExtendedImage.file(
- file,
- fit: BoxFit.contain,
- //enableSlideOutPage: true,
- mode: ExtendedImageMode.gesture,
- initGestureConfigHandler: (state) {
- double initialScale = 1.0;
-
- if (state.extendedImageInfo != null &&
- state.extendedImageInfo.image != null) {
- initialScale = initScale(
- size: size,
- initialScale: initialScale,
- imageSize: Size(
- state.extendedImageInfo.image.width.toDouble(),
- state.extendedImageInfo.image.height
- .toDouble()));
- }
- return GestureConfig(
- inPageView: true,
- initialScale: initialScale,
- maxScale: max(initialScale, 5.0),
- initialAlignment: InitialAlignment.topCenter,
- animationMaxScale: max(initialScale, 5.0),
- //you can cache gesture state even though page view page change.
- //remember call clearGestureDetailsCache() method at the right time.(for example,this page dispose)
- cacheGesture: false);
- },
- onDoubleTap: (ExtendedImageGestureState state) {
- //you can use define pointerDownPosition as you can,
- //default value is double tap pointer down postion.
- var pointerDownPosition = state.pointerDownPosition;
- double begin = state.gestureDetails.totalScale;
- double end;
-
- //remove old
- _animation?.removeListener(animationListener);
-
- //stop pre
- _animationController.stop();
-
- //reset to use
- _animationController.reset();
-
- if (begin == doubleTapScales[0]) {
- end = doubleTapScales[1];
- } else {
- end = doubleTapScales[0];
- }
-
- animationListener = () {
- //print(_animation.value);
- state.handleDoubleTap(
- scale: _animation.value,
- doubleTapPosition: pointerDownPosition);
- };
- _animation = _animationController
- .drive(Tween<double>(begin: begin, end: end));
-
- _animation.addListener(animationListener);
-
- _animationController.forward();
- },
- );
- } else {
- image = ExtendedImage.network(
- picUrl,
- fit: BoxFit.contain,
- // enableSlideOutPage: true,
- mode: ExtendedImageMode.gesture,
- initGestureConfigHandler: (state) {
- double initialScale = 1.0;
-
- if (state.extendedImageInfo != null &&
- state.extendedImageInfo.image != null) {
- initialScale = initScale(
- size: size,
- initialScale: initialScale,
- imageSize: Size(
- state.extendedImageInfo.image.width.toDouble(),
- state.extendedImageInfo.image.height
- .toDouble()));
- }
- return GestureConfig(
- inPageView: true,
- initialScale: initialScale,
- maxScale: max(initialScale, 5.0),
- initialAlignment: InitialAlignment.topCenter,
- animationMaxScale: max(initialScale, 5.0),
- //you can cache gesture state even though page view page change.
- //remember call clearGestureDetailsCache() method at the right time.(for example,this page dispose)
- cacheGesture: false);
- },
- onDoubleTap: (ExtendedImageGestureState state) {
- //you can use define pointerDownPosition as you can,
- //default value is double tap pointer down postion.
- var pointerDownPosition = state.pointerDownPosition;
- double begin = state.gestureDetails.totalScale;
- double end;
-
- //remove old
- _animation?.removeListener(animationListener);
-
- //stop pre
- _animationController.stop();
-
- //reset to use
- _animationController.reset();
-
- if (begin == doubleTapScales[0]) {
- end = doubleTapScales[1];
- } else {
- end = doubleTapScales[0];
- }
-
- animationListener = () {
- //print(_animation.value);
- state.handleDoubleTap(
- scale: _animation.value,
- doubleTapPosition: pointerDownPosition);
- };
- _animation = _animationController
- .drive(Tween<double>(begin: begin, end: end));
-
- _animation.addListener(animationListener);
-
- _animationController.forward();
- },
- );
- }
-
- image = GestureDetector(
- child: Container(
- child: image,
- ),
- onTap: () {
- slidePagekey.currentState.popPage();
- Navigator.pop(context);
- },
- );
- //滤镜背景
- var bg = Center(
- child: ClipRect(
- //裁切长方形
- child: BackdropFilter(
- //背景滤镜器
- filter: ui.ImageFilter.blur(
- sigmaX: 20.0, sigmaY: 20.0), //图片模糊过滤,横向竖向都设置5.0
- child: Opacity(
- //透明控件
- opacity: 0.5,
- child: Container(
- alignment: Alignment.center,
- width: Screen.width,
- height: Screen.height,
- color: Colors.black,
- ),
- ),
- ),
- ),
- );
-
- //焚阅照片
- if ((item.type == PhotoType.destroy.index ||
- item.type == PhotoType.destroyMoney.index &&
- item.isBuy) &&
- item.userId != UserData().basicInfo.userId) {
- image = GestureDetector(
- onLongPress: item.isWatch
- ? null
- : () {
- browsePhoto(item.id, item.userId, 1, () {
- _startTimer();
- setState(() {});
- });
- },
- onLongPressEnd: item.isWatch
- ? null
- : (detail) {
- _cancelTimer();
- setState(() {});
- },
- onTap: () {
- slidePagekey.currentState.popPage();
- Navigator.pop(context);
- },
- child: Container(
- color: Colors.grey.shade200,
- child: Stack(
- alignment: Alignment.center,
- children: <Widget>[
- image,
- isShow
- ? Container()
- : Stack(
- alignment: Alignment.center,
- children: <Widget>[
- bg,
- item.isWatch
- ? Container(
- height: 211,
- width: 275.5,
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius:
- BorderRadius.all(
- Radius.circular(
- 5))),
- child: Column(
- mainAxisAlignment:
- MainAxisAlignment.center,
- children: <Widget>[
- Icon(
- IconData(
- 0xe634,
- fontFamily: 'iconfont',
- ),
- color: const Color(
- 0xFFA7A7A7),
- size: 50,
- ),
- fixedText(
- I18n.of(context)
- .destroyed,
- fontSize: 16,
- color: const Color(
- 0xFFA7A7A7)),
- UserData().isVip ||
- UserData()
- .basicInfo
- .sex ==
- 2
- ? Container()
- : fixedText(
- I18n.of(context)
- .longTime,
- color: Colors
- .grey[700],
- fontSize: 12),
- UserData().isVip ||
- UserData()
- .basicInfo
- .sex ==
- 2
- ? Container()
- : SizedBox(height: 10),
- UserData().isVip ||
- UserData()
- .basicInfo
- .sex ==
- 2
- ? Container()
- : RaisedButton(
- color: Colors.blue,
- onPressed: () {
- Navigator.of(
- context)
- .push(
- new MaterialPageRoute(
- builder:
- (context) {
- return VipPage();
- },
- ),
- );
- },
- child: fixedText(
- I18n.of(context)
- .joinvip,
- color: Colors
- .white),
- )
- ],
- ))
- : Container(
- height: 211,
- width: 275.5,
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius:
- BorderRadius.all(
- Radius.circular(
- 5))),
- child: Column(
- mainAxisAlignment:
- MainAxisAlignment.start,
- children: <Widget>[
- Padding(
- padding:
- EdgeInsets.only(
- top: 10,
- bottom: 2),
- child: Icon(
- IconData(
- 0xe634,
- fontFamily:
- 'iconfont',
- ),
- color: const Color(
- 0xFFF44236),
- size: 50,
- )),
- fixedText(
- I18n.of(context)
- .destroy_after,
- color: const Color(
- 0xFFF44236),
- fontSize: 15),
- Padding(
- padding: EdgeInsets.only(
- top: 25, bottom: 15),
- child: fixedText(
- I18n.of(context)
- .longClick,
- color: const Color(
- 0xFFFA8880),
- fontSize: 12),
- ),
- Image.asset(
- 'assets/images/zhiwen.png',
- height: 55,
- )
- ],
- ))
- ],
- )
- ],
- )));
- }
-
- //红包照片
- if ((item.type == PhotoType.money.index ||
- (item.type == PhotoType.destroyMoney.index &&
- !item.isBuy)) &&
- item.userId != UserData().basicInfo.userId) {
- image = GestureDetector(
- onTap: () {
- slidePagekey.currentState.popPage();
- Navigator.pop(context);
- },
- child: Container(
- color: Colors.grey.shade200,
- child: Stack(
- alignment: Alignment.center,
- children: <Widget>[
- image,
- item.isBuy
- ? Container()
- : Stack(
- alignment: Alignment.center,
- children: <Widget>[
- bg,
- Stack(
- alignment: Alignment.center,
- children: <Widget>[
- Image.asset(
- 'assets/images/login/money.png',
- fit: BoxFit.fitWidth,
- width: 220,
- ),
- Container(
- margin: EdgeInsets.only(top: 65),
- child: fixedText(
- I18n.of(context)
- .less_coin
- .replaceFirst(
- '/s1',
- UserData()
- .redPhotoPrice
- .toString()),
- color:
- const Color(0xFFFAE6B4),
- fontSize: 25),
- ),
- InkWell(
- onTap: () {
- CustomUI.buildOneConfirm(
- context,
- I18n.of(context)
- .pay_unlock
- .replaceFirst(
- '/s1',
- UserData()
- .redPhotoPrice
- .toString()),
- I18n.of(context)
- .confirm_pay, () {
- browsePhoto(
- item.id, item.userId, 2,
- () {
- setState(() {
- Navigator.of(context)
- .pop();
- MessageMgr().emit(
- 'refresh_photo',
- item.id);
- item.isBuy = true;
- });
- },
- price: UserData()
- .redPhotoPrice);
- });
- },
- child: Container(
- decoration: BoxDecoration(
- color: const Color(
- 0xFFFAE6B4),
- borderRadius:
- BorderRadius.all(
- Radius.circular(
- 30))),
- padding: EdgeInsets.only(
- left: 40,
- right: 40,
- top: 5,
- bottom: 5),
- margin:
- EdgeInsets.only(top: 140),
- child: fixedText(
- I18n.of(context)
- .determine,
- color: const Color(
- 0xFF7B0408)),
- ))
- ],
- )
- ],
- )
- ],
- )));
- }
-
- if (index == currentIndex) {
- return Hero(
- tag: picUrl + index.toString(),
- child: image,
- flightShuttleBuilder: (BuildContext flightContext,
- Animation<double> animation,
- HeroFlightDirection flightDirection,
- BuildContext fromHeroContext,
- BuildContext toHeroContext) {
- final Hero hero =
- flightDirection == HeroFlightDirection.pop
- ? fromHeroContext.widget
- : toHeroContext.widget;
- return hero.child;
- },
- );
- } else {
- return image;
- }
- },
- itemCount: widget.pics.length,
- onPageChanged: (int index) {
- currentIndex = index;
- rebuildIndex.add(index);
- },
- controller: PageController(
- initialPage: currentIndex,
- ),
- scrollDirection: Axis.horizontal,
- physics: BouncingScrollPhysics(),
- ),
- _seconds == 0
- ? Container()
- : Container(
- padding: EdgeInsets.only(bottom: 30),
- alignment: Alignment.bottomCenter,
- child: Stack(
- alignment: Alignment.center,
- children: <Widget>[
- CircularProgressIndicator(
- strokeWidth: 4.0,
- backgroundColor: Colors.grey,
- value: _seconds / 6,
- valueColor:
- new AlwaysStoppedAnimation<Color>(Colors.red),
- ),
- fixedText(_seconds.toString(), color: Colors.red)
- // Positioned(
- // top: 8,
- // left: 13,
- // child:
- // fixedText(_seconds.toString(), color: Colors.red),
- // )
- ],
- )),
- ],
- ));
-
- result = ExtendedImageSlidePage(
- key: slidePagekey,
- child: result,
- slideAxis: SlideAxis.both,
- slideType: SlideType.onlyImage,
- onSlidingPage: (state) {
- ///you can change other widgets' state on page as you want
- ///base on offset/isSliding etc
- //var offset= state.offset;
- var showSwiper = !state.isSliding;
- if (showSwiper != _showSwiper) {
- // do not setState directly here, the image state will change,
- // you should only notify the widgets which are needed to change
- // setState(() {
- // _showSwiper = showSwiper;
- // });
-
- _showSwiper = showSwiper;
- rebuildSwiper.add(_showSwiper);
- }
- },
- );
-
- return result;
- }
- }
-
- class MySwiperPlugin extends StatelessWidget {
- final List<PicSwiperItem> pics;
- final int index;
- final StreamController<int> reBuild;
- final bool isMyself;
- final callback;
- MySwiperPlugin(
- this.pics, this.index, this.reBuild, this.isMyself, this.callback);
- @override
- Widget build(BuildContext context) {
- return StreamBuilder<int>(
- builder: (BuildContext context, data) {
- return DefaultTextStyle(
- style: TextStyle(color: Colors.white),
- child: Container(
- //alignment: Alignment.center,
- height: 50.0,
- width: double.infinity,
- color: Colors.white,
- child: Row(
- children: <Widget>[
- InkWell(
- onTap: () {
- Navigator.of(context).pop();
- },
- child: Container(
- margin: EdgeInsets.only(left: 10),
- child: Icon(
- Icons.chevron_left,
- color: Constants.BlackTextColor,
- )),
- ),
- Expanded(
- child: Container(
- alignment: Alignment.center,
- child: fixedText("${data.data + 1} / ${pics.length}",
- color: Constants.BlackTextColor))),
- isMyself
- ? InkWell(
- onTap: () {
- CustomUI.buildOneConfirm(
- context,
- I18n.of(context).sure_delete,
- I18n.of(context).determine, () {
- callback(index);
- Navigator.of(context).pop();
- });
- },
- child: Container(
- margin: EdgeInsets.only(right: 10),
- child: Icon(
- Icons.delete,
- color: Constants.BlackTextColor,
- )),
- )
- : Container(),
- ],
- )),
- );
- },
- initialData: index,
- stream: reBuild.stream,
- );
- }
- }
-
- class PicSwiperItem {
- var userId;
- int id;
- String picUrl;
- String des;
- File file;
- int type;
- bool isBuy; //是否购买
- bool isWatch; //是否观看
- PicSwiperItem(
- this.picUrl, {
- this.file,
- this.id,
- this.des = "",
- this.type = 0,
- this.isBuy = false,
- this.isWatch = false,
- this.userId,
- });
- }
|