Browse Source

latest

teso_v2
Benjamin Arhen 3 years ago
parent
commit
d430cec0a9
  1. 19
      .idea/libraries/Dart_SDK.xml
  2. 15
      .idea/libraries/KotlinJavaRuntime.xml
  3. 9
      .idea/modules.xml
  4. 6
      .idea/runConfigurations/main_dart.xml
  5. 36
      .idea/workspace.xml
  6. 10
      .metadata
  7. 29
      analysis_options.yaml
  8. 22
      android/app/build.gradle
  9. 3
      android/app/src/main/AndroidManifest.xml
  10. 2
      android/app/src/main/res/values/styles.xml
  11. 6
      android/build.gradle
  12. 2
      lib/Classes/NotificationSpliter.dart
  13. 1
      lib/Classes/TextE.dart
  14. 31
      lib/Classes/Uploading.dart
  15. 1
      lib/Classes/customLoginButton.dart
  16. 1
      lib/Classes/customTesoButton.dart
  17. 48
      lib/GeneralWidgets/widgets/uservideo_player_widget.dart
  18. 104
      lib/GeneralWidgets/widgets/video_player_widget.dart
  19. 1
      lib/GeneralWidgets/widgets/widgets.dart
  20. 141
      lib/Pages/Campaigns.dart
  21. 142
      lib/Pages/PageWidgets/Campaigns/campaignTile.dart
  22. 45
      lib/Pages/PageWidgets/Campaigns/header.dart
  23. 1
      lib/Pages/PageWidgets/Home/homeTile.dart
  24. 1
      lib/Pages/PageWidgets/Login/bottomCurve.dart
  25. 137
      lib/Pages/PageWidgets/Posts/comment.dart
  26. 40
      lib/Pages/PageWidgets/Posts/posted.dart
  27. 56
      lib/Pages/PageWidgets/Posts/user3P_commentTitle.dart
  28. 69
      lib/Pages/PageWidgets/Posts/user_commentTitle.dart
  29. 35
      lib/Pages/PageWidgets/Posts/user_posted.dart
  30. 1
      lib/Pages/PageWidgets/Third Person Profile/header.dart
  31. 89
      lib/Pages/PageWidgets/Uploads/Pending.dart
  32. 10
      lib/Pages/Personnal.dart
  33. 212
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/TextEditor.dart
  34. 840
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/VideoReview copy.dart
  35. 554
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/VideoReview.dart
  36. 92
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/color_palette.dart
  37. 30
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/option_button.dart
  38. 87
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/toolbar.dart
  39. 8
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/toolbar_action.dart
  40. 24
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/background_color_tool.dart
  41. 24
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_color_tool.dart
  42. 66
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_family_tool.dart
  43. 123
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_size_tool.dart
  44. 237
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/text_format_tool.dart
  45. 223
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/text_style_editor.dart
  46. 499
      lib/Pages/Sub_Pages/@Generic/Camera/Video/RecordVideo.dart
  47. 45
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/file_formats.dart
  48. 32
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/storage_dir.dart
  49. 81
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/thumbnail_viewer.dart
  50. 537
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart
  51. 150
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor_painter.dart
  52. 300
      lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart
  53. 1
      lib/Pages/Sub_Pages/AccountSettings/newPassword.dart
  54. 153
      lib/Pages/Sub_Pages/Campaign/AuditionPage.dart
  55. 200
      lib/Pages/Sub_Pages/Campaign/CreatePost.dart
  56. 195
      lib/Pages/Sub_Pages/Campaign/SubmitAdvert.dart
  57. 212
      lib/Pages/Sub_Pages/Campaign/Video/Editor/TextEditor.dart
  58. 560
      lib/Pages/Sub_Pages/Campaign/Video/Editor/VideoReview.dart
  59. 92
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/color_palette.dart
  60. 30
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/option_button.dart
  61. 87
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/toolbar.dart
  62. 8
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/toolbar_action.dart
  63. 24
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/background_color_tool.dart
  64. 24
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_color_tool.dart
  65. 66
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_family_tool.dart
  66. 123
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_size_tool.dart
  67. 237
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/text_format_tool.dart
  68. 226
      lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/text_style_editor.dart
  69. 500
      lib/Pages/Sub_Pages/Campaign/Video/RecordVideo.dart
  70. 45
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/file_formats.dart
  71. 32
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/storage_dir.dart
  72. 81
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/thumbnail_viewer.dart
  73. 537
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor.dart
  74. 150
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor_painter.dart
  75. 300
      lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trimmer.dart
  76. 2
      lib/Pages/Sub_Pages/LandingPage/Login.dart
  77. 2
      lib/Pages/Sub_Pages/LandingPage/createPassword.dart
  78. 2
      lib/Pages/Sub_Pages/Notifications/ChatScreen.dart
  79. 92
      lib/Pages/Sub_Pages/PersonalSub/Posts.dart
  80. 196
      lib/Pages/Sub_Pages/Posts/CreatePost.dart
  81. 585
      lib/Pages/Sub_Pages/Posts/SpecialPosts.dart
  82. 515
      lib/Pages/Sub_Pages/Posts/UserPosts.dart
  83. 920
      lib/Pages/Sub_Pages/Posts/ViewPost.dart
  84. 332
      lib/Pages/Sub_Pages/Posts/comment.dart
  85. 155
      lib/Pages/Sub_Pages/Posts/deletePost.dart
  86. 103
      lib/Pages/Sub_Pages/Posts/postedDetails.dart
  87. 289
      lib/Pages/Sub_Pages/Posts/user_comment.dart
  88. 204
      lib/Pages/Sub_Pages/homeSub/HomeFeed.dart
  89. 66
      lib/Pages/Sub_Pages/homeSub/VideoList.dart
  90. 27
      lib/Pages/Sub_Pages/userProfile3P.dart
  91. 1
      lib/Pages/codeQR.dart
  92. 189
      lib/Pages/home.dart
  93. 1
      lib/Services/services.dart
  94. 1
      lib/Services/services2.dart
  95. 67
      lib/Services/uservideo_controller_service.dart
  96. 66
      lib/Services/video_controller_service.dart
  97. 1
      lib/blocs/blocs.dart
  98. 3
      lib/blocs/video_player/uservideo_player.dart
  99. 28
      lib/blocs/video_player/uservideo_player_bloc.dart
  100. 16
      lib/blocs/video_player/uservideo_player_event.dart

19
.idea/libraries/Dart_SDK.xml

@ -0,0 +1,19 @@
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/async" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/core" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/html" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/io" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/math" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://D:\flutter/bin/cache/dart-sdk/lib/typed_data" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

15
.idea/libraries/KotlinJavaRuntime.xml

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="KotlinJavaRuntime">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-test.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-stdlib-sources.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect-sources.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-test-sources.jar!/" />
</SOURCES>
</library>
</component>

9
.idea/modules.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/teso.iml" filepath="$PROJECT_DIR$/teso.iml" />
<module fileurl="file://$PROJECT_DIR$/android/teso_android.iml" filepath="$PROJECT_DIR$/android/teso_android.iml" />
</modules>
</component>
</project>

6
.idea/runConfigurations/main_dart.xml

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="filePath" value="$PROJECT_DIR$/lib/main.dart" />
<method />
</configuration>
</component>

36
.idea/workspace.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="ToolWindowManager">
<editor active="true" />
<layout>
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
</layout>
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
</navigator>
<panes>
<pane id="ProjectPane">
<option name="show-excluded-files" value="false" />
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="dart.analysis.tool.window.force.activate" value="true" />
<property name="show.migrate.to.gradle.popup" value="false" />
</component>
</project>

10
.metadata

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: db747aa1331bd95bc9b3874c842261ca2d302cd5
channel: stable
project_type: app

29
analysis_options.yaml

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
#include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

22
android/app/build.gradle

@ -54,6 +54,7 @@ android {
applicationId "com.sparentechBacware.teso"
minSdkVersion 21
targetSdkVersion 31
ndkVersion '23.1.7779620'
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
@ -75,18 +76,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// buildTypes {
// release {
// // TODO: Add your own signing config for the release build.
// // Signing with the debug keys for now, so `flutter run --release` works.
// ndk {
// abiFilters 'armeabi-v7a','arm64-v8a','x86_64'
// }
// minifyEnabled true
// signingConfig signingConfigs.debug
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// }
// }
}
@ -103,12 +92,5 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
implementation 'com.github.AbedElazizShe:LightCompressor:0.9.4'
def camerax_version = "1.0.0"
// CameraX core library using camera2 implementation
implementation "androidx.camera:camera-camera2:$camerax_version"
// CameraX Lifecycle Library
implementation "androidx.camera:camera-lifecycle:$camerax_version"
// CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha24"
}

3
android/app/src/main/AndroidManifest.xml

@ -31,7 +31,7 @@
<data android:scheme="https" />
</intent>
</queries>
<application android:name="io.flutter.app.FlutterApplication" android:label="Teso" tools:replace="label" android:icon="@mipmap/ic_launcher" android:requestLegacyExternalStorage="true" android:usesCleartextTraffic="true">
<application android:name="${applicationName}" android:label="Teso" tools:replace="label" android:icon="@mipmap/ic_launcher" android:requestLegacyExternalStorage="true" android:usesCleartextTraffic="true">
<meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyB3gbhILEzrSCFpxE509PnEb7slCkBfBQI" />
<meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="ocr,label" />
<activity android:name=".MainActivity" android:launchMode="singleTop"
@ -44,7 +44,6 @@
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" />
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
<meta-data android:name="flutterEmbedding" android:value="2" />
<intent-filter>

2
android/app/src/main/res/values/styles.xml

@ -13,6 +13,6 @@
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

6
android/build.gradle

@ -43,9 +43,9 @@ subprojects {
project.evaluationDependsOn(':app')
}
ext {
flutterFFmpegPackage = "full-gpl-lts"
}
// ext {
// flutterFFmpegPackage = "full-gpl-lts"
// }

2
lib/Classes/NotificationSpliter.dart

@ -16,13 +16,11 @@ class NotificationSplitter {
return payload;
break;
case "likes":
Provider.of<UserProvider>(context, listen: false).pullAds();
payload.loadID = "TESN000";
payload.load1 = data["post"];
return payload;
break;
case "comments":
Provider.of<UserProvider>(context, listen: false).pullAds();
payload.loadID = "TESN000";
payload.load1 = data["post"];
return payload;

1
lib/Classes/TextE.dart

@ -1,4 +1,3 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class Textted {

31
lib/Classes/Uploading.dart

@ -1,31 +0,0 @@
import 'package:flutter_upchunk/flutter_upchunk.dart';
class Uploading {
String id;
String title;
String path;
String aspect;
String thumbnail;
UpChunk token;
double pending;
String campaignID;
String muxuploadID;
String muxuploadURL;
String muxassetID;
bool isProcessing;
Uploading({
this.id,
this.title,
this.path,
this.aspect,
this.thumbnail,
this.token,
this.pending,
this.campaignID,
this.isProcessing,
this.muxuploadID,
this.muxuploadURL,
this.muxassetID,
});
}

1
lib/Classes/customLoginButton.dart

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CustomLoginButton extends StatelessWidget {

1
lib/Classes/customTesoButton.dart

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class RaisedGradientButton extends StatelessWidget {

48
lib/GeneralWidgets/widgets/uservideo_player_widget.dart

@ -1,48 +0,0 @@
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
const ASPECT_RATIO = 16 / 9;
class VideoPlayerWidget extends StatefulWidget {
final BetterPlayerController controller;
final FBPosts ad;
const VideoPlayerWidget({
Key key,
@required this.controller,
@required this.ad,
}) : assert(controller != null),
assert(ad != null),
super(key: key);
@override
_VideoPlayerWidgetState createState() => _VideoPlayerWidgetState();
}
class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return FittedBox(
clipBehavior: Clip.hardEdge,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: BetterPlayer(
controller: widget.controller,
),
),
);
}
@override
void dispose() {
widget.controller.dispose();
super.dispose();
}
}

104
lib/GeneralWidgets/widgets/video_player_widget.dart

@ -1,104 +0,0 @@
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:teso/Classes/API%20Clasess/CouponDetails.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Pages/Sub_Pages/ProductDetails/CouponList.dart';
import 'package:teso/providers/user_provider.dart';
const ASPECT_RATIO = 16 / 9;
class VideoPlayerWidget extends StatefulWidget {
final BetterPlayerController controller;
final Post ad;
final bool play;
final List<CouponDetails> details;
const VideoPlayerWidget({
Key key,
@required this.controller,
@required this.ad,
@required this.play,
this.details,
}) : assert(controller != null),
assert(ad != null),
super(key: key);
@override
_VideoPlayerWidgetState createState() => _VideoPlayerWidgetState();
}
class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
bool displayed = false;
@override
void initState() {
widget.controller.videoPlayerController.addListener(() => checkVideo());
super.initState();
// if (widget.play) {
// _chewieController.play();
// }
}
checkVideo() async {
// Implement your calls inside these conditions' bodies :
if (widget.controller.videoPlayerController.value.position ==
Duration(seconds: 0, minutes: 0, hours: 0)) {
// print('video Started');
Provider.of<UserProvider>(context, listen: false).viewPost(widget.ad);
}
if (widget.controller.videoPlayerController.value.position.inSeconds >
(widget.controller.videoPlayerController.value.duration.inSeconds) /
3) {
// print('video Ended');
if (!displayed && widget.details.length > 0) {
setState(() {
displayed = true;
});
await Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
pageBuilder: (_, __, ___) => CouponList(
couponsList: widget.details,
),
),
);
}
// _chewieController.play();
}
}
// @override
// void didUpdateWidget(VideoPlayerWidget oldWidget) {
// if (oldWidget.play != widget.play) {
// if (widget.play) {
// _chewieController.play();
// } else {
// _chewieController.pause();
// }
// }
// super.didUpdateWidget(oldWidget);
// }
@override
Widget build(BuildContext context) {
return FittedBox(
clipBehavior: Clip.hardEdge,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: BetterPlayer(
controller: widget.controller,
),
),
);
}
@override
void dispose() {
widget.controller.dispose();
super.dispose();
}
}

1
lib/GeneralWidgets/widgets/widgets.dart

@ -1 +0,0 @@
export 'video_player_widget.dart';

141
lib/Pages/Campaigns.dart

@ -1,141 +0,0 @@
import 'package:flutter/material.dart';
import 'PageWidgets/Campaigns/header.dart';
import 'package:teso/Classes/API Clasess/Campaign.dart';
import 'PageWidgets/Campaigns/campaignTile.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/util/consts.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class Campaigns extends StatefulWidget {
@override
_CampaignsState createState() => _CampaignsState();
}
class _CampaignsState extends State<Campaigns> {
TextEditingController searchkey;
List<Campaign> campaignMain;
List<Campaign> campaign;
var _future;
void clearText() {
setState(() {
searchkey.clear();
});
}
Future<List<Campaign>> getCampaigns() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Authorization': prefs.getString('tokensTeso')
};
var register2 = serverLocation + 'adverts/businesscampaigns';
var client1 = await http.post(Uri.parse(register2),
body: json.encode(searchkey.text), headers: requestHeaders);
if (client1.statusCode == 200) {
var details = jsonDecode(client1.body);
if (mounted)
setState(() {
campaign = List<Campaign>.from(
details.map((model) => Campaign.fromJSON(model)).toList());
});
if (campaignMain == null) {
setState(() {
campaignMain = campaign;
});
}
}
return campaign;
}
@override
void initState() {
super.initState();
searchkey = new TextEditingController();
_future = getCampaigns();
searchkey.addListener(() async {
if (searchkey.text.isNotEmpty) {
getCampaigns();
} else {
setState(() {
campaign = campaignMain;
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: true,
title: Text("Join a Campaign"),
centerTitle: true,
),
body: Container(
// padding: EdgeInsets.only(
// left: 10,
// right: 10,
// ),
child: Column(
children: [
buildCampaignHead(context, searchkey, clearText),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
child: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.waiting) {
return Container(
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
);
} else if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.done) {
return Container(
height: MediaQuery.of(context).size.width,
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
"Sorry there are no open campaigns at the moment"),
),
);
} else {
return ListView.builder(
primary: true,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: campaign.length,
itemBuilder: (context, index) {
return buildCampaign(
context,
campaign.elementAt(index),
);
},
);
}
},
),
),
),
],
),
),
);
}
}

142
lib/Pages/PageWidgets/Campaigns/campaignTile.dart

@ -1,142 +0,0 @@
import 'package:flutter/material.dart';
import 'package:teso/Classes/API Clasess/Campaign.dart';
import 'package:teso/providers/pageAnimations.dart';
import 'package:teso/util/consts.dart';
import 'package:jiffy/jiffy.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/AuditionPage.dart';
buildCampaign(BuildContext context, Campaign campaignItem) {
return Container(
width: MediaQuery.of(context).size.width,
//height: 120,
// padding: EdgeInsets.only(
// left: 10,
// right: 10,
// ),
child: Material(
elevation: 2.5,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 90,
height: 95,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 0.5,
),
borderRadius: BorderRadius.only(
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
child: Image(
width: MediaQuery.of(context).size.width * 0.28,
height: 110,
fit: BoxFit.fill,
image: NetworkImage(campaignItem.targetProduct != null
? productURL + campaignItem.targetProduct
: ""),
),
),
),
Container(
width: MediaQuery.of(context).size.width - 105,
//height: 110,
padding: EdgeInsets.all(5),
child: Column(
children: [
Container(
width: double.infinity,
child: Wrap(
direction: Axis.horizontal,
children: [
Text(
"Campaign Title : ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(campaignItem.title)
],
),
),
Container(
width: double.infinity,
child: Wrap(
direction: Axis.horizontal,
children: [
Text(
"Description : ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
campaignItem.description.length > 90
? campaignItem.description.substring(0, 90) +
"...."
: campaignItem.description,
)
],
),
),
Container(
width: double.infinity,
child: Wrap(
direction: Axis.horizontal,
children: [
Text(
"Start Date : ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(Jiffy(campaignItem.startDate).yMMMMd),
],
),
),
Container(
width: double.infinity,
child: Align(
alignment: Alignment.centerRight,
child: Container(
width: 90,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
),
primary: accentMain,
),
onPressed: () => Navigator.push(
context,
PageTransition(
child: Audition(
campaign: campaignItem,
),
type: PageTransitionType.rightToLeft,
),
),
child: Text("Join"),
),
),
),
),
],
),
),
],
),
),
),
);
}

45
lib/Pages/PageWidgets/Campaigns/header.dart

@ -1,45 +0,0 @@
import 'package:flutter/material.dart';
buildCampaignHead(
BuildContext context, TextEditingController searchkey, Function filter) {
return Container(
height: 60.0,
//margin: EdgeInsets.all(10.0),
padding: EdgeInsets.all(10.0),
child: Material(
elevation: 4.0,
borderRadius: BorderRadius.circular(12.0),
shadowColor: Theme.of(context).backgroundColor,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
//buildSmartSearch(context),
new Expanded(
child: InkWell(
onTap: () => print("Searching"),
child: TextField(
autofocus: false,
enabled: true,
textAlign: TextAlign.start,
controller: searchkey,
onChanged: (String v) => filter(v),
style: TextStyle(
color: Theme.of(context).primaryColorLight,
),
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: Icon(
Icons.search,
color: Theme.of(context).primaryColorLight,
),
hintText: "Search",
hintStyle: TextStyle(color: Colors.grey),
),
),
),
),
],
),
),
);
}

1
lib/Pages/PageWidgets/Home/homeTile.dart

@ -1,5 +1,4 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/util/consts.dart';

1
lib/Pages/PageWidgets/Login/bottomCurve.dart

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
class CurvePainter extends CustomPainter {
@override

137
lib/Pages/PageWidgets/Posts/comment.dart

@ -1,137 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
buildCommentTile(BuildContext context, bool available, Uint8List bytes,
TextEditingController controller) {
return Container(
width: MediaQuery.of(context).size.width,
height: 170,
margin: EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
child: Material(
elevation: 50.0,
borderRadius: BorderRadius.circular(12.0),
child: InkWell(
onTap: () {
// Navigator.push(
// context,
// PageTransition(
// type: PageTransitionType.rightToLeft,
// child: CommentSection(),
// ),
// );
},
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 10),
height: 30,
width: double.infinity,
child: Center(
child: Text(
"Comments",
style: TextStyle(
fontSize: 16,
),
),
),
),
Divider(),
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
width: double.infinity,
child: Text("Love this post ? Say something!")),
GestureDetector(
onTap: () => print("hello"),
child: Container(
padding: EdgeInsets.symmetric(
vertical: 08,
horizontal: 6,
),
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Container(
height: 45.0,
width: 50.0,
margin: EdgeInsets.only(right: 8),
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
child: !available
? Center(
child: Text("B"),
)
: Image(
fit: BoxFit.fill,
image: MemoryImage(bytes),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.55,
height: 50,
child: TextField(
maxLines: 2,
autofocus: false,
enabled: true,
textAlign: TextAlign.start,
controller: controller,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
border: InputBorder.none,
//contentPadding: EdgeInsets.only(top: 14.0),
hintText: "Add a comment",
hintStyle: TextStyle(color: Colors.grey),
),
),
),
GestureDetector(
onTap: () {
print("send comment");
},
child: Container(
margin: EdgeInsets.all(20),
height: 30,
width: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Color.fromRGBO(0, 0, 0, 0.4),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
child: Align(
alignment: Alignment.center,
child: Icon(
Icons.send,
)),
),
),
),
],
),
),
),
],
),
),
),
),
);
}

40
lib/Pages/PageWidgets/Posts/posted.dart

@ -1,40 +0,0 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:flutter/material.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/Pages/Sub_Pages/Posts/SpecialPosts.dart';
import 'package:teso/providers/pageAnimations.dart';
import 'package:teso/util/consts.dart';
buildPosted(BuildContext context, Post post, double height, TesoUser user,
bool addable) {
return Container(
margin: EdgeInsets.all(3),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.width * height,
color: Colors.black,
child: GestureDetector(
onTap: () {
Navigator.push(
context,
PageTransition(
child: new ViewPost(
postedAd: post,
play: true,
),
type: PageTransitionType.fade));
},
child: CachedNetworkImage(
imageUrl: tesoPostThumb(post.playbackID),
imageBuilder: (context, imageProvider) => FadeInImage(
width: double.infinity,
fit: BoxFit.fill,
image: imageProvider,
placeholder: AssetImage("assets/images/blank.jpg"),
),
errorWidget: (context, url, error) =>
Image.asset("assets/images/blank.jpg"),
),
),
);
}

56
lib/Pages/PageWidgets/Posts/user3P_commentTitle.dart

@ -1,56 +0,0 @@
import 'package:flutter/material.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/util/consts.dart';
import 'package:time_elapsed/time_elapsed.dart';
buildPostTile3P(BuildContext context, TesoUser user, Post postedAd) {
return ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(
serverLocation + "api/pulldp/" + postedAd.publisherID,
),
placeholder: AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: user.username + " ",
style: new TextStyle(fontWeight: FontWeight.bold)),
new TextSpan(
text: postedAd.title,
),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(postedAd.timestamp),
),
);
}

69
lib/Pages/PageWidgets/Posts/user_commentTitle.dart

@ -1,69 +0,0 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:teso/Classes/API%20Clasess/PostedAd.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:time_elapsed/time_elapsed.dart';
buildPostTile(BuildContext context, PostedAd postedAd) {
return Consumer<UserProvider>(
builder: (context, value, child) {
return ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: value.currentUser.thumbnail_dp == null
? Center(
child: Text(
value.currentUser.username.characters
.characterAt(0)
.toString()
.toUpperCase(),
),
)
: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(
userdpURL + value.currentUser.thumbnail_dp),
placeholder: AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: value.currentUser.username + " ",
style: new TextStyle(fontWeight: FontWeight.bold)),
new TextSpan(
text: postedAd.post.title,
),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(postedAd.post.timestamp),
),
);
},
);
}

35
lib/Pages/PageWidgets/Posts/user_posted.dart

@ -1,35 +0,0 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
import 'package:teso/Pages/Sub_Pages/Posts/UserPosts.dart';
import 'package:teso/util/consts.dart';
buildPosted(BuildContext context, FBPosts post, double height) {
return Container(
margin: EdgeInsets.all(3),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.width * height,
color: Colors.black,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(new PageRouteBuilder(
pageBuilder: (_, __, ___) => new UserPosts(postedAd: post),
));
},
child: CachedNetworkImage(
imageUrl: tesoPostThumb(
post.playbackID,
),
imageBuilder: (context, imageProvider) => FadeInImage(
width: double.infinity,
fit: BoxFit.fill,
image: imageProvider,
placeholder: AssetImage("assets/images/blank.jpg"),
),
errorWidget: (context, url, error) => Container(
color: Colors.grey[800],
),
),
),
);
}

1
lib/Pages/PageWidgets/Third Person Profile/header.dart

@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/util/consts.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
buildHead(
{BuildContext context,

89
lib/Pages/PageWidgets/Uploads/Pending.dart

@ -1,89 +0,0 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:loading_indicator/loading_indicator.dart';
import 'package:provider/provider.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
uploadTile(BuildContext context, Uploading pendingUpload) {
return Card(
child: Container(
width: MediaQuery.of(context).size.width,
height: 70,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
//constraints: BoxConstraints(minHeight: 80, maxHeight: 150),
width: 60,
height: 60,
child: pendingUpload != null && pendingUpload.thumbnail != null
? Image(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
image: MemoryImage(base64Decode(pendingUpload.thumbnail)),
gaplessPlayback: true,
)
: Image(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
image: AssetImage(
"assets/images/blank.jpg",
),
gaplessPlayback: true,
),
),
pendingUpload.isProcessing
? new Wrap(
direction: Axis.vertical,
children: [
Text("Preparing post.."),
LoadingIndicator(
indicatorType: Indicator.ballPulse,
/// Required, The loading type of the widget
colors: [tesoAsh, tesoBlue, tesoGold],
/// Optional, The color collections
strokeWidth: 2,
/// Optional, The stroke of the line, only applicable to widget which contains line
)
],
)
: new Wrap(
direction: Axis.vertical,
children: [
Text("Processing.."),
Container(
width: MediaQuery.of(context).size.width * 0.65,
height: 10,
child: LinearProgressIndicator(
value: pendingUpload.pending,
backgroundColor: tesoAsh,
valueColor: new AlwaysStoppedAnimation<Color>(tesoBlue),
),
),
],
),
pendingUpload.isProcessing
? Container()
: Container(
width: 40,
height: 40,
child: InkWell(
onTap: () =>
Provider.of<UserProvider>(context, listen: false)
.cancelUpload(pendingUpload),
child: Icon(Icons.close),
),
),
],
),
),
);
}

10
lib/Pages/Personnal.dart

@ -5,7 +5,6 @@ import 'package:teso/util/consts.dart';
import 'package:flutter/material.dart';
import 'package:teso/Pages/PageWidgets/Personal/header.dart';
import 'package:teso/Pages/Sub_Pages/PersonalSub/Friends.dart';
import 'package:teso/Pages/Sub_Pages/PersonalSub/Posts.dart';
import 'package:teso/Pages/Sub_Pages/PersonalSub/Recently.dart';
import 'package:teso/providers/user_provider.dart';
@ -61,14 +60,12 @@ class _PersonnalState extends State<Personnal> with TickerProviderStateMixin {
switch (tabsController.index) {
case 0:
await Provider.of<UserProvider>(context, listen: false).pullAds();
Provider.of<UserProvider>(context, listen: false).loadFriends();
Provider.of<UserProvider>(context, listen: false).getCoupons();
break;
case 1:
await Provider.of<UserProvider>(context, listen: false).loadFriends();
Provider.of<UserProvider>(context, listen: false).getCoupons();
Provider.of<UserProvider>(context, listen: false).pullAds();
break;
default:
break;
@ -79,7 +76,7 @@ class _PersonnalState extends State<Personnal> with TickerProviderStateMixin {
@override
void initState() {
super.initState();
tabsController = new TabController(length: 3, initialIndex: 0, vsync: this);
tabsController = new TabController(length: 2, initialIndex: 0, vsync: this);
}
@override
@ -150,9 +147,7 @@ class _PersonnalState extends State<Personnal> with TickerProviderStateMixin {
),
controller: tabsController,
tabs: [
Tab(
text: "Posts",
),
Tab(
text: "Friends",
),
@ -173,7 +168,6 @@ class _PersonnalState extends State<Personnal> with TickerProviderStateMixin {
child: TabBarView(
controller: tabsController,
children: [
Posts(),
Friends(),
Recently(),
],

212
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/TextEditor.dart

@ -1,212 +0,0 @@
// import 'package:flutter/material.dart';
// import 'package:teso/Classes/TextE.dart';
// import 'package:teso/util/SizeConfig.dart';
// import 'textstyler/src/toolbar_action.dart';
// import 'textstyler/text_style_editor.dart';
// // ignore: must_be_immutable
// class TextEdit extends StatefulWidget {
// Textted content;
// TextEdit({Key key, this.content}) : super(key: key);
// @override
// _TextEditState createState() => _TextEditState();
// }
// class _TextEditState extends State<TextEdit> {
// TextStyle textStyle;
// TextAlign textAlign;
// List<String> fonts = [
// 'Billabong',
// 'AlexBrush',
// 'Allura',
// 'Arizonia',
// 'ChunkFive',
// 'GrandHotel',
// 'GreatVibes',
// 'Lobster',
// 'OpenSans',
// 'OstrichSans',
// 'Oswald',
// 'Pacifico',
// 'Quicksand',
// 'Roboto',
// 'SEASRN',
// 'Windsong',
// ];
// List<Color> paletteColors = [
// Colors.black,
// Colors.white,
// Color(int.parse('0xffEA2027')),
// Color(int.parse('0xff006266')),
// Color(int.parse('0xff1B1464')),
// Color(int.parse('0xff5758BB')),
// Color(int.parse('0xff6F1E51')),
// Color(int.parse('0xffB53471')),
// Color(int.parse('0xffEE5A24')),
// Color(int.parse('0xff009432')),
// Color(int.parse('0xff0652DD')),
// Color(int.parse('0xff9980FA')),
// Color(int.parse('0xff833471')),
// Color(int.parse('0xff112CBC4')),
// Color(int.parse('0xffFDA7DF')),
// Color(int.parse('0xffED4C67')),
// Color(int.parse('0xffF79F1F')),
// Color(int.parse('0xffA3CB38')),
// Color(int.parse('0xff1289A7')),
// Color(int.parse('0xffD980FA'))
// ];
// FocusNode _focus = new FocusNode();
// TextEditingController controller;
// @override
// void initState() {
// controller = new TextEditingController();
// textStyle = TextStyle(
// fontSize: 15,
// color: Colors.white,
// fontFamily: 'OpenSans',
// );
// textAlign = TextAlign.left;
// _focus.addListener(_onFocusChange);
// controller.text = widget.content.text != null ? widget.content.text : "";
// textStyle =
// widget.content.textStyle != null ? widget.content.textStyle : null;
// textAlign = widget.content.textAlign != null
// ? widget.content.textAlign
// : TextAlign.center;
// super.initState();
// }
// @override
// void dispose() {
// _focus.removeListener(_onFocusChange);
// _focus.dispose();
// super.dispose();
// }
// void _onFocusChange() {
// debugPrint("Focus: " + _focus.hasFocus.toString());
// }
// void verify() {
// if (_focus.hasFocus) {
// _focus.unfocus();
// } else {
// Navigator.pop(
// context,
// new Textted(
// text: controller.text,
// textAlign: textAlign,
// textStyle: textStyle,
// ));
// }
// }
// @override
// Widget build(BuildContext context) {
// SizeConfig().init(context);
// return Scaffold(
// resizeToAvoidBottomInset: false,
// backgroundColor: Color.fromRGBO(0, 0, 0, 0.8),
// appBar: AppBar(
// backgroundColor: Colors.transparent,
// leading: IconButton(
// onPressed: () => Navigator.pop(context, widget.content),
// icon: Icon(
// Feather.x,
// color: Colors.white,
// ),
// ),
// actions: [
// IconButton(
// onPressed: verify,
// icon: Icon(
// AntDesign.check,
// color: Colors.white,
// ),
// ),
// ],
// ),
// body: Container(
// height: SizeConfig.safeBlockVertical * 40,
// child: Center(
// child: TextField(
// controller: controller,
// // enabled: false,
// focusNode: _focus,
// style: textStyle,
// textAlign: textAlign,
// // maxLines: 4,
// decoration: new InputDecoration(
// filled: true,
// enabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(10.0),
// ),
// borderSide: BorderSide(
// color: Colors.grey.shade400,
// width: 2,
// ),
// ),
// focusedBorder: OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(10.0),
// ),
// borderSide: BorderSide(
// color: Colors.blue.shade300,
// width: 0,
// ),
// ),
// contentPadding: EdgeInsets.all(15),
// ),
// ),
// ),
// ),
// extendBody: false,
// extendBodyBehindAppBar: false,
// bottomSheet: Container(
// height: SizeConfig.safeBlockVertical * 60,
// child: Container(
// padding: EdgeInsets.all(10),
// decoration: BoxDecoration(
// color: Theme.of(context).backgroundColor,
// border: Border.symmetric(
// horizontal: BorderSide(
// color: Theme.of(context).backgroundColor,
// ),
// ),
// ),
// child: Align(
// alignment: Alignment.topCenter,
// child: SingleChildScrollView(
// scrollDirection: Axis.vertical,
// child: TextStyleEditor(
// fonts: fonts,
// paletteColors: paletteColors,
// textStyle: textStyle,
// textAlign: textAlign,
// initialTool: EditorToolbarAction.fontFamilyTool,
// onTextAlignEdited: (align) {
// setState(() {
// textAlign = align;
// });
// },
// onTextStyleEdited: (style) {
// setState(() {
// textStyle = textStyle.merge(style);
// });
// },
// onCpasLockTaggle: (caps) {
// print(caps);
// },
// //onToolbarActionChanged: (fu) => ,
// ),
// ),
// ),
// ),
// ),
// );
// }
// }

840
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/VideoReview copy.dart

@ -1,840 +0,0 @@
// import 'dart:typed_data';
// import 'package:firebase_crashlytics/firebase_crashlytics.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter/rendering.dart';
// import 'package:flutter/services.dart';
// import 'dart:io';
//
// import 'package:image_gallery_saver/image_gallery_saver.dart';
// import 'package:page_transition/page_transition.dart';
// import 'package:share_plus/share_plus.dart';
// import 'package:teso/Classes/TextE.dart';
// import 'package:teso/Pages/PageWidgets/Editors/SampleThumbnail.dart';
// import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Editor/TextEditor.dart';
// import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart';
// import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart';
// import 'package:teso/Pages/Sub_Pages/Posts/CreatePost.dart';
// import 'package:teso/util/SizeConfig.dart';
// import 'package:video_player/video_player.dart';
// import 'package:teso/util/consts.dart';
// import 'dart:async';
// import 'package:path_provider/path_provider.dart';
// import 'package:teso/Classes/TesoUser.dart';
// import 'package:provider/provider.dart';
// import 'package:teso/providers/user_provider.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:image/image.dart' as IMG;
// import 'package:video_thumbnail/video_thumbnail.dart';
// import 'package:teso/Classes/ColorFilters.dart';
// class VideoReview extends StatefulWidget {
// final video;
// final bool recorded;
// const VideoReview({Key key, @required this.video, @required this.recorded})
// : super(key: key);
// @override
// _VideoReviewState createState() => _VideoReviewState();
// }
// class _VideoReviewState extends State<VideoReview>
// with TickerProviderStateMixin {
// Trimmer _trimmer = new Trimmer();
// VideoPlayerController videoController;
// VoidCallback videoPlayerListener;
// bool muted = false;
// String readyVideo;
// Color textColor = Colors.white;
// double _startValue = 0.15;
// double _endValue = 60000.0;
// var _future;
// bool _isPlaying = false;
// Duration _duration;
// Duration _position;
// ByteData bytes;
// Uint8List imageBitmap;
// Uint8List thumbnail;
// Directory tempDirectory;
// TesoUser user;
// bool processing = false;
// bool downloaded = false;
// bool processed = false;
// final key = new GlobalKey();
// double currentOffset = 0;
// // ScreenshotController screenshotController = ScreenshotController();
// Offset offset = Offset(0, SizeConfig.safeBlockVertical * 50);
// var indexFilter = 0;
// ScrollController controller;
// TextStyle textStyle;
// TextAlign textAlign;
// bool showFilter = false;
// Textted editting = new Textted();
// List<String> fonts = [
// 'Billabong',
// 'AlexBrush',
// 'Allura',
// 'Arizonia',
// 'ChunkFive',
// 'GrandHotel',
// 'GreatVibes',
// 'Lobster',
// 'OpenSans',
// 'OstrichSans',
// 'Oswald',
// 'Pacifico',
// 'Quicksand',
// 'Roboto',
// 'SEASRN',
// 'Windsong',
// ];
// List<Color> paletteColors = [
// Colors.black,
// Colors.white,
// Color(int.parse('0xffEA2027')),
// Color(int.parse('0xff006266')),
// Color(int.parse('0xff1B1464')),
// Color(int.parse('0xff5758BB')),
// Color(int.parse('0xff6F1E51')),
// Color(int.parse('0xffB53471')),
// Color(int.parse('0xffEE5A24')),
// Color(int.parse('0xff009432')),
// Color(int.parse('0xff0652DD')),
// Color(int.parse('0xff9980FA')),
// Color(int.parse('0xff833471')),
// Color(int.parse('0xff112CBC4')),
// Color(int.parse('0xffFDA7DF')),
// Color(int.parse('0xffED4C67')),
// Color(int.parse('0xffF79F1F')),
// Color(int.parse('0xffA3CB38')),
// Color(int.parse('0xff1289A7')),
// Color(int.parse('0xffD980FA'))
// ];
// List<ColorFilter> colorFilters = [
// new ColorFilter(code: Color(0xFFffffff), name: "Original"),
// new ColorFilter(code: Color(0xFFffffff), name: "White"),
// new ColorFilter(code: Color(0xFF5E2612), name: "Sepia"),
// new ColorFilter(code: Color(0xFF8BA446), name: "Martini Olive"),
// new ColorFilter(code: Color(0xFFFFF8DC), name: "Cornsilk"),
// new ColorFilter(code: Color(0xFFCDB7B5), name: "Mistyrose"),
// new ColorFilter(code: Color(0xFFEEE9E9), name: "Snow"),
// new ColorFilter(code: Color(0xFF856363), name: "Dusty"),
// new ColorFilter(code: Color(0xFF8C1717), name: "Scarlet"),
// new ColorFilter(code: Color(0xFF615E3F), name: "Tank"),
// ];
// void _scrollListener() {
// setState(() {
// indexFilter =
// (controller.offset / MediaQuery.of(context).size.width).round() + 1;
// if (controller.offset > currentOffset) {
// controller.animateTo(currentOffset + MediaQuery.of(context).size.width,
// duration: Duration(microseconds: 2), curve: Curves.easeIn);
// currentOffset = controller.offset;
// } else {
// controller.animateTo(currentOffset - MediaQuery.of(context).size.width,
// duration: Duration(microseconds: 2), curve: Curves.easeIn);
// currentOffset = controller.offset;
// }
// });
// print(indexFilter);
// }
// Future<void> _startVideoPlayer() async {
// await videoController.play();
// }
// Future<void> initializeController(String fileLocation) async {
// videoController = VideoPlayerController.file(File(fileLocation));
// videoPlayerListener = () async {
// Timer.run(() {
// this.setState(() {
// _position = videoController.value.position;
// });
// setState(() {
// _duration = Duration(milliseconds: _endValue.round());
// });
// if (_duration?.compareTo(_position) == 0 ||
// _duration?.compareTo(_position) == -1) {
// this.setState(() {
// _isPlaying = false;
// });
// videoController.pause();
// videoController.seekTo(Duration(milliseconds: _startValue.round()));
// } else {}
// });
// };
// videoController.addListener(videoPlayerListener);
// await videoController.setLooping(true);
// await videoController.initialize();
// await _trimmer.loadVideo(videoFile: File(fileLocation));
// }
// @override
// void initState() {
// // textStyle = TextStyle(
// // fontSize: 15,
// // color: Colors.white,
// // fontFamily: 'OpenSans',
// // );
// controller = new ScrollController();
// controller.addListener(_scrollListener);
// readyVideo = widget.video;
// if (readyVideo != null) _future = initializeController(readyVideo);
// rootBundle.load("assets/images/rawLogo.png").then((value) => setState(() {
// imageBitmap = value.buffer.asUint8List();
// IMG.Image img = IMG.decodeImage(imageBitmap);
// IMG.Image resized = IMG.copyResize(img, width: 50, height: 60);
// imageBitmap = IMG.encodePng(resized);
// }));
// super.initState();
// editting =
// new Textted(text: "", textAlign: textAlign, textStyle: textStyle);
// }
// Future<Uint8List> saveTextOverlay() async {
// return await screenshotController.capture(
// pixelRatio: videoController.value.aspectRatio);
// }
// @override
// void dispose() {
// videoController?.dispose();
// controller.dispose();
// super.dispose();
// }
// void postVideo(context) async {
// setState(() {
// processing = true;
// });
// if (processed) {
// await Navigator.pushReplacement(
// context,
// PageTransition(
// type: PageTransitionType.leftToRight,
// child: CreatePost(
// video: readyVideo,
// aspectRatio: videoController.value.aspectRatio.toString(),
// thumbnail: this.thumbnail,
// ),
// ));
// } else {
// readyVideo = await processVideo(context, false);
// await Navigator.pushReplacement(
// context,
// PageTransition(
// type: PageTransitionType.leftToRight,
// child: CreatePost(
// video: readyVideo,
// aspectRatio: videoController.value.aspectRatio.toString(),
// thumbnail: this.thumbnail,
// ),
// ));
// }
// }
// Future<void> downloadVideo(context) async {
// try {
// setState(() {
// processing = true;
// });
// String output = await processVideo(context, true);
// await ImageGallerySaver.saveFile(output).catchError((error, stackTrace) {
// setState(() {
// processing = false;
// downloaded = false;
// });
// }).then((value) {
// setState(() {
// processing = false;
// downloaded = true;
// });
// });
// } catch (e) {
// print(e);
// }
// }
// Future<String> processVideo(context, bool watermark) async {
// user = Provider.of<UserProvider>(context, listen: false).currentUser;
// String location = await getTemporaryDirectory().then((value) =>
// value.path +
// "/" +
// DateTime.now().millisecondsSinceEpoch.toString() +
// ".mp4");
// String initial = await _trimmer.saveTrimmedVideo(
// applyVideoEncoding: false,
// startValue: _startValue,
// endValue: videoController.value.duration.inMilliseconds > 5900 &&
// videoController.value.duration.inMilliseconds >= _endValue
// ? _endValue
// : double.parse(
// videoController.value.duration.inMilliseconds.toString()),
// );
// this.thumbnail = await generateThumbnail();
// if (widget.recorded) {
// try {
// // Uint8List textBytes;
// // if (editting.text.isNotEmpty) textBytes = await saveTextOverlay();
// // int xposition = ScaledPosition.getWidth(
// // SizeConfig.safeBlockHorizontal * 100,
// // videoController.value.size.width,
// // offset.dx);
// // int yposition = ScaledPosition.getHeight(
// // SizeConfig.safeBlockVertical * 100,
// // videoController.value.size.height,
// // offset.dy);
// // if (watermark) {
// // final tapiocaBalls = [
// // if (indexFilter > 1)
// // TapiocaBall.filterFromColor(colorFilters[indexFilter - 1].code),
// // TapiocaBall.imageOverlay(imageBitmap, 0, 0),
// // if (textBytes != null)
// // TapiocaBall.imageOverlay(textBytes, xposition, yposition),
// // ];
// // final cup = Cup(Content(initial), tapiocaBalls);
// // await cup.suckUp(location);
// // setState(() {
// // processed = true;
// // });
// // } else if (!watermark && indexFilter == 1) {
// // setState(() {
// // processed = true;
// // });
// // final tapiocaBalls = [
// // if (textBytes != null)
// // TapiocaBall.imageOverlay(textBytes, xposition, yposition),
// // ];
// // final cup = Cup(Content(initial), tapiocaBalls);
// // await cup.suckUp(location);
// // } else {
// // final tapiocaBalls = [
// // if (indexFilter != 1 && indexFilter != 0)
// // TapiocaBall.filterFromColor(colorFilters[indexFilter - 1].code),
// // if (textBytes != null)
// // TapiocaBall.imageOverlay(textBytes, xposition, yposition),
// // ];
// // final cup = Cup(Content(initial), tapiocaBalls);
// // await cup.suckUp(location);
// // setState(() {
// // processed = true;
// // });
// // }
// } catch (e) {
// print(e);
// FirebaseCrashlytics.instance.recordError(
// e,
// e,
// reason: "Video Editor",
// );
// setState(() {
// processed = true;
// });
// }
// } else {
// location = initial;
// }
// return location;
// }
// Future<Uint8List> generateThumbnail() async {
// try {
// Uint8List thumbnail;
// thumbnail = await VideoThumbnail.thumbnailData(
// video: widget.video,
// imageFormat: ImageFormat.JPEG,
// maxWidth: 0,
// maxHeight: 0,
// timeMs: 100,
// quality: 100,
// );
// return thumbnail;
// } catch (e) {
// print("Error :::: " + e);
// return null;
// }
// }
// Future<void> shareVideo(context) async {
// setState(() {
// processing = true;
// });
// if (readyVideo == widget.video) {
// readyVideo = await processVideo(context, true);
// Share.shareFiles([readyVideo]);
// } else {
// Share.shareFiles([readyVideo]);
// }
// setState(() {
// processing = false;
// });
// }
// void setText() async {
// Textted ed = await Navigator.push(
// context,
// PageRouteBuilder(
// opaque: false,
// pageBuilder: (_, __, ___) => TextEdit(
// content: editting,
// ),
// ),
// );
// if (ed != null) {
// setState(() {
// editting = ed;
// });
// }
// }
// void showFilters() async {
// if (thumbnail == null) this.thumbnail = await generateThumbnail();
// setState(() {
// showFilter = !showFilter;
// });
// }
// void setFilter(index) {
// setState(() {
// indexFilter = index;
// });
// }
// @override
// Widget build(BuildContext context) {
// SizeConfig().init(context);
// return Scaffold(
// body: FutureBuilder(
// future: _future,
// builder: (context, snapshot) {
// if (snapshot.connectionState == ConnectionState.waiting) {
// return Container(
// color: Colors.black,
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// child: Center(
// child: CircularProgressIndicator(
// backgroundColor: Colors.red,
// ),
// ),
// );
// } else {
// return Stack(
// children: [
// videoContent(context),
// // //Filters
// filterWidget(context),
// textWidget(context),
// // Video trimmer
// trimmerWidget(context),
// // Pop button
// Align(
// alignment: Alignment.topLeft,
// child: InkWell(
// onTap: () => Navigator.pop(context),
// child: Container(
// margin: EdgeInsets.symmetric(
// horizontal: MediaQuery.of(context).size.width * 0.07,
// vertical: MediaQuery.of(context).size.width * 0.1,
// ),
// height: 35,
// width: 35,
// decoration: BoxDecoration(
// color: Color.fromRGBO(0, 0, 0, 0.4),
// shape: BoxShape.circle),
// child: Icon(
// EvilIcons.close,
// color: Colors.white,
// size: 20,
// ),
// ),
// ),
// ),
// //Filter Buttons
// showFilter ? listFilters(context) : Container(),
// // Bottom buttons
// bottomButtons(context),
// Visibility(
// visible: processing,
// child: Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// color: Color.fromRGBO(0, 0, 0, 0.6),
// padding: EdgeInsets.only(
// top: MediaQuery.of(context).size.width * 0.7),
// child: Center(
// child: Column(
// children: [
// Image.asset(cupertinoActivityIndicatorSmall),
// Text(
// "Processing.....",
// style: TextStyle(
// color: Colors.white,
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// );
// }
// }),
// );
// }
// Widget trimmerWidget(context) {
// return Container(
// margin: EdgeInsets.symmetric(
// horizontal: MediaQuery.of(context).size.width * 0.01,
// vertical: MediaQuery.of(context).size.width * 0.20,
// ),
// width: MediaQuery.of(context).size.width,
// child: TrimEditor(
// borderPaintColor: tesoGold,
// circlePaintColor: tesoBlue,
// thumbnailQuality: 100,
// showDuration: true,
// viewerHeight: 50.0,
// maxVideoLength: Duration(seconds: 60),
// viewerWidth: MediaQuery.of(context).size.width,
// onChangeStart: (value) {
// if (!mounted) {
// setState(() {
// _startValue = value;
// });
// } else {
// _startValue = value;
// }
// videoController.seekTo(Duration(milliseconds: value.round()));
// },
// onChangeEnd: (value) {
// if (!mounted) {
// setState(() {
// _endValue = value;
// });
// } else {
// _endValue = value;
// }
// },
// onChangePlaybackState: (isPlaying) {
// if (mounted)
// setState(() {
// _isPlaying = isPlaying;
// });
// },
// ));
// }
// Widget filterWidget(context) {
// return GestureDetector(
// onTap: () {
// !_isPlaying ? _startVideoPlayer() : videoController.pause();
// setState(() {
// _isPlaying = !_isPlaying;
// });
// },
// child: Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// color:
// colorFilters.elementAt(indexFilter).name.toLowerCase() == "original"
// ? colorFilters.elementAt(indexFilter).code.withOpacity(0)
// : colorFilters.elementAt(indexFilter).code.withOpacity(0.5),
// ),
// );
// }
// Widget videoContent(context) {
// print(videoController.value.size.width);
// return Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// color: Colors.black,
// child: Center(
// child: AspectRatio(
// aspectRatio: videoController.value.size != null
// ? videoController.value.aspectRatio
// : 1.0,
// child: Stack(
// children: [
// InkWell(
// onTap: () {
// !_isPlaying ? _startVideoPlayer() : videoController.pause();
// setState(() {
// _isPlaying = !_isPlaying;
// });
// },
// child: VideoPlayer(
// videoController,
// ),
// ),
// Container(
// width: double.infinity,
// height: double.infinity,
// child: GestureDetector(
// child: !_isPlaying
// ? Icon(
// Ionicons.md_play_circle,
// size: 60,
// color: Colors.white,
// )
// : Container(),
// onTap: () {
// !_isPlaying
// ? _startVideoPlayer()
// : videoController.pause();
// setState(() {
// _isPlaying = !_isPlaying;
// });
// },
// ),
// ),
// ],
// )),
// ),
// );
// }
// Widget bottomButtons(context) {
// if (widget.recorded) {
// return Align(
// alignment: Alignment.bottomLeft,
// child: Container(
// margin: EdgeInsets.symmetric(
// horizontal: MediaQuery.of(context).size.width * 0.05,
// vertical: SizeConfig.safeBlockVertical * 2.5,
// ),
// width: MediaQuery.of(context).size.width,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// mainAxisSize: MainAxisSize.min,
// children: [
// Container(
// width: 55,
// height: 40,
// padding: EdgeInsets.all(5),
// decoration: BoxDecoration(
// color: Color.fromRGBO(0, 0, 0, 0.6),
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
// bottomRight: Radius.circular(30),
// topRight: Radius.circular(30),
// topLeft: Radius.circular(30),
// ),
// border: Border.all(color: Colors.white, width: 0.5)),
// child: InkWell(
// onTap: () async =>
// !downloaded ? await downloadVideo(context) : null,
// child: Icon(
// !downloaded ? Feather.download : MaterialIcons.check,
// color: !downloaded ? Colors.white : Colors.green,
// ),
// ),
// ),
// // InkWell(
// // onTap: setText,
// // child: Container(
// // width: 50,
// // padding: EdgeInsets.symmetric(horizontal: 18),
// // decoration: BoxDecoration(
// // color: Color.fromRGBO(0, 0, 0, 0.6),
// // borderRadius: BorderRadius.only(
// // bottomLeft: Radius.circular(30),
// // bottomRight: Radius.circular(30),
// // topRight: Radius.circular(30),
// // topLeft: Radius.circular(30),
// // ),
// // border: Border.all(color: Colors.white, width: 0.5)),
// // child: Text(
// // "T",
// // style: TextStyle(
// // color: Colors.white,
// // fontWeight: FontWeight.bold,
// // fontSize: SizeConfig.safeBlockHorizontal * 8,
// // fontFamily: 'DeadheadScript',
// // ),
// // ),
// // ),
// // ),
// // Container(
// // width: 55,
// // height: 40,
// // padding: EdgeInsets.all(5),
// // decoration: BoxDecoration(
// // color: Color.fromRGBO(0, 0, 0, 0.6),
// // borderRadius: BorderRadius.only(
// // bottomLeft: Radius.circular(30),
// // bottomRight: Radius.circular(30),
// // topRight: Radius.circular(30),
// // topLeft: Radius.circular(30),
// // ),
// // border: Border.all(color: Colors.white, width: 0.5)),
// // child: InkWell(
// // onTap: showFilters,
// // child: Image(
// // image: AssetImage("assets/images/color-filters.png"),
// // ),
// // ),
// // ),
// Container(
// width: 55,
// height: 40,
// padding: EdgeInsets.all(5),
// decoration: BoxDecoration(
// color: Color.fromRGBO(0, 0, 0, 0.6),
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
// bottomRight: Radius.circular(30),
// topRight: Radius.circular(30),
// topLeft: Radius.circular(30),
// ),
// border: Border.all(color: Colors.white, width: 0.5)),
// child: InkWell(
// onTap: () async => await shareVideo(context),
// child: Icon(
// Entypo.share,
// color: Colors.white,
// ),
// ),
// ),
// Container(
// padding: EdgeInsets.all(5),
// width: 100,
// height: 40,
// decoration: BoxDecoration(
// color: tesoGold,
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
// bottomRight: Radius.circular(30),
// topRight: Radius.circular(30),
// topLeft: Radius.circular(30),
// ),
// ),
// child: InkWell(
// onTap: () => postVideo(context),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Text(
// "Post",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// ),
// ),
// Icon(
// Ionicons.md_send,
// color: tesoBlue,
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// );
// } else {
// return Align(
// alignment: Alignment.bottomRight,
// child: Container(
// padding: EdgeInsets.all(5),
// width: 100,
// height: 40,
// margin: EdgeInsets.symmetric(
// vertical: 10,
// horizontal: 20,
// ),
// decoration: BoxDecoration(
// color: tesoGold,
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
// bottomRight: Radius.circular(30),
// topRight: Radius.circular(30),
// topLeft: Radius.circular(30),
// ),
// ),
// child: InkWell(
// onTap: () => postVideo(context),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Text(
// "Post",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// ),
// ),
// Icon(
// Ionicons.md_send,
// color: tesoBlue,
// ),
// ],
// ),
// ),
// ),
// );
// }
// }
// Widget listFilters(context) {
// return Align(
// alignment: Alignment.bottomLeft,
// child: Container(
// margin: EdgeInsets.symmetric(
// horizontal: MediaQuery.of(context).size.width * 0.05,
// vertical: SizeConfig.safeBlockVertical * 10,
// ),
// width: MediaQuery.of(context).size.width,
// height: SizeConfig.safeBlockVertical * 17,
// child: ListView.builder(
// scrollDirection: Axis.horizontal,
// itemCount: colorFilters.length,
// //controller: controller,
// itemBuilder: (context, index) {
// return InkWell(
// onTap: () => setFilter(index),
// child: buildFilterThumb(
// context, colorFilters[index], thumbnail));
// }),
// ),
// );
// }
// Widget textWidget(context) {
// return Container(
// child: Positioned(
// left: offset.dx,
// top: offset.dy,
// child: GestureDetector(
// onTap: setText,
// onPanUpdate: (details) {
// setState(() {
// offset = Offset(
// offset.dx + details.delta.dx, offset.dy + details.delta.dy);
// });
// },
// child: Screenshot(
// controller: screenshotController,
// child: editting.text != null
// ? Text(
// editting.text,
// style: editting.textStyle,
// textAlign: editting.textAlign,
// )
// : Container(),
// ),
// ),
// ),
// );
// }
// }

554
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/VideoReview.dart

@ -1,554 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share_plus/share_plus.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/file_formats.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart';
import 'package:teso/Pages/Sub_Pages/Posts/CreatePost.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:video_player/video_player.dart';
import 'package:teso/util/consts.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:provider/provider.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:flutter/cupertino.dart';
import 'package:image/image.dart' as IMG;
import 'package:video_thumbnail/video_thumbnail.dart';
class VideoReview extends StatefulWidget {
final video;
final bool recorded;
final double aspect;
const VideoReview(
{Key key, @required this.video, @required this.recorded, this.aspect})
: super(key: key);
@override
_VideoReviewState createState() => _VideoReviewState();
}
class _VideoReviewState extends State<VideoReview>
with TickerProviderStateMixin {
Trimmer _trimmer = new Trimmer();
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
bool muted = false;
String readyVideo;
Color textColor = Colors.white;
double _startValue = 0.15;
double _endValue = 60000.0;
var _future;
bool _isPlaying = false;
Duration _duration;
Duration _position;
ByteData bytes;
Uint8List imageBitmap;
Uint8List thumbnail;
Directory tempDirectory;
TesoUser user;
bool processing = false;
bool downloaded = false;
bool processed = false;
final key = new GlobalKey();
double currentOffset = 0;
Future<void> _startVideoPlayer() async {
await videoController.play();
}
Future<void> initializeController(String fileLocation) async {
videoController = VideoPlayerController.file(File(fileLocation));
videoPlayerListener = () async {
Timer.run(() {
this.setState(() {
_position = videoController.value.position;
});
setState(() {
_duration = Duration(milliseconds: _endValue.round());
});
if (_duration?.compareTo(_position) == 0 ||
_duration?.compareTo(_position) == -1) {
this.setState(() {
_isPlaying = false;
});
videoController.pause();
videoController.seekTo(Duration(milliseconds: _startValue.round()));
} else {}
});
};
videoController.addListener(videoPlayerListener);
await videoController.setLooping(true);
await videoController.initialize();
await _trimmer.loadVideo(videoFile: File(fileLocation));
}
@override
void initState() {
readyVideo = widget.video;
if (readyVideo != null) _future = initializeController(readyVideo);
rootBundle.load("assets/images/rawLogo.png").then((value) => setState(() {
imageBitmap = value.buffer.asUint8List();
IMG.Image img = IMG.decodeImage(imageBitmap);
IMG.Image resized = IMG.copyResize(img, width: 50, height: 60);
imageBitmap = IMG.encodePng(resized);
}));
super.initState();
}
@override
void dispose() {
super.dispose();
videoController.dispose();
}
void postVideo(context) async {
setState(() {
processing = true;
});
if (processed) {
await Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: CreatePost(
video: readyVideo,
aspectRatio: widget.recorded
? "0.5625"
: videoController.value.aspectRatio.toString(),
thumbnail: this.thumbnail,
),
));
} else {
readyVideo = await processVideo(context, false);
await Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: CreatePost(
video: readyVideo,
aspectRatio: widget.recorded
? "0.5625"
: videoController.value.aspectRatio.toString(),
thumbnail: this.thumbnail,
),
));
}
}
Future<void> downloadVideo(context) async {
try {
setState(() {
processing = true;
});
String output = await processVideo(context, true);
await ImageGallerySaver.saveFile(output).catchError((error, stackTrace) {
setState(() {
processing = false;
downloaded = false;
});
}).then((value) {
setState(() {
processing = false;
downloaded = true;
});
});
} catch (e) {
print(e);
}
}
Future<String> processVideo(context, bool watermark) async {
user = Provider.of<UserProvider>(context, listen: false).currentUser;
String location = await getTemporaryDirectory().then((value) =>
value.path +
"/" +
DateTime.now().millisecondsSinceEpoch.toString() +
".mp4");
if (widget.recorded) {
String initial = await _trimmer.saveTrimmedVideo(
applyVideoEncoding: false,
ffmpegCommand: "-vf setsar=1:1 -aspect 9:16",
customVideoFormat: ".mp4",
startValue: _startValue,
endValue: videoController.value.duration.inMilliseconds > 5900 &&
videoController.value.duration.inMilliseconds >= _endValue
? _endValue
: double.parse(
videoController.value.duration.inMilliseconds.toString()),
);
this.thumbnail = await generateThumbnail();
location = initial;
} else {
String initial = await _trimmer.saveTrimmedVideo(
startValue: _startValue,
endValue: videoController.value.duration.inMilliseconds > 5900 &&
videoController.value.duration.inMilliseconds >= _endValue
? _endValue
: double.parse(
videoController.value.duration.inMilliseconds.toString()),
outputFormat: FileFormat.mp4,
);
this.thumbnail = await generateThumbnail();
location = initial;
}
return location;
}
Future<Uint8List> generateThumbnail() async {
try {
Uint8List thumbnail;
thumbnail = await VideoThumbnail.thumbnailData(
video: widget.video,
imageFormat: ImageFormat.JPEG,
maxWidth: 0,
maxHeight: 0,
timeMs: 100,
quality: 100,
);
return thumbnail;
} catch (e) {
print("Error :::: " + e);
return null;
}
}
Future<void> shareVideo(context) async {
setState(() {
processing = true;
});
if (readyVideo == widget.video) {
readyVideo = await processVideo(context, true);
Share.shareFiles([readyVideo]);
} else {
Share.shareFiles([readyVideo]);
}
setState(() {
processing = false;
});
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container(
color: Colors.black,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.red,
),
),
);
} else {
return Stack(
children: [
videoContent(context),
// Video trimmer
trimmerWidget(context),
// Pop button
Align(
alignment: Alignment.topLeft,
child: InkWell(
onTap: () => Navigator.pop(context),
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.07,
vertical: MediaQuery.of(context).size.width * 0.1,
),
height: 35,
width: 35,
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.4),
shape: BoxShape.circle),
child: Icon(
Icons.close,
color: Colors.white,
size: 20,
),
),
),
),
// Bottom buttons
bottomButtons(context),
Visibility(
visible: processing,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Color.fromRGBO(0, 0, 0, 0.6),
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width * 0.7),
child: Center(
child: Column(
children: [
CupertinoActivityIndicator(
animating: true,
radius: 15,
),
Text(
"Processing.....",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
),
),
],
);
}
}),
);
}
Widget trimmerWidget(context) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.01,
vertical: MediaQuery.of(context).size.width * 0.20,
),
width: MediaQuery.of(context).size.width,
child: TrimEditor(
borderPaintColor: tesoGold,
circlePaintColor: tesoBlue,
thumbnailQuality: 100,
showDuration: true,
viewerHeight: 50.0,
maxVideoLength: Duration(seconds: 60),
viewerWidth: MediaQuery.of(context).size.width,
onChangeStart: (value) {
if (!mounted) {
setState(() {
_startValue = value;
});
} else {
_startValue = value;
}
videoController.seekTo(Duration(milliseconds: value.round()));
},
onChangeEnd: (value) {
if (!mounted) {
setState(() {
_endValue = value;
});
} else {
_endValue = value;
}
},
onChangePlaybackState: (isPlaying) {
if (mounted)
setState(() {
_isPlaying = isPlaying;
});
},
));
}
Widget videoContent(context) {
print(videoController.value.size.width);
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Center(
child: AspectRatio(
aspectRatio: videoController.value.size != null
? videoController.value.aspectRatio
: 1.0,
child: Stack(
children: [
InkWell(
onTap: () {
!_isPlaying ? _startVideoPlayer() : videoController.pause();
setState(() {
_isPlaying = !_isPlaying;
});
},
child: VideoPlayer(
videoController,
),
),
Container(
width: double.infinity,
height: double.infinity,
child: GestureDetector(
child: !_isPlaying
? Icon(
Icons.play_circle,
size: 60,
color: Colors.white,
)
: Container(),
onTap: () {
!_isPlaying
? _startVideoPlayer()
: videoController.pause();
setState(() {
_isPlaying = !_isPlaying;
});
},
),
),
],
)),
),
);
}
Widget bottomButtons(context) {
if (widget.recorded) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05,
vertical: SizeConfig.safeBlockVertical * 2.5,
),
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 55,
height: 40,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.6),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
border: Border.all(color: Colors.white, width: 0.5)),
child: InkWell(
onTap: () async =>
!downloaded ? await downloadVideo(context) : null,
child: Icon(
!downloaded ? Icons.download : Icons.check,
color: !downloaded ? Colors.white : Colors.green,
),
),
),
Container(
width: 55,
height: 40,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.6),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
border: Border.all(color: Colors.white, width: 0.5)),
child: InkWell(
onTap: () async => await shareVideo(context),
child: Icon(
Icons.share,
color: Colors.white,
),
),
),
Container(
padding: EdgeInsets.all(5),
width: 100,
height: 40,
decoration: BoxDecoration(
color: tesoGold,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
),
child: InkWell(
onTap: () => postVideo(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Post",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
Icon(
Icons.send,
color: tesoBlue,
),
],
),
),
),
],
),
),
);
} else {
return Align(
alignment: Alignment.bottomRight,
child: Container(
padding: EdgeInsets.all(5),
width: 100,
height: 40,
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 20,
),
decoration: BoxDecoration(
color: tesoGold,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
),
child: InkWell(
onTap: () => postVideo(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Post",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
Icon(
Icons.send,
color: tesoBlue,
),
],
),
),
),
);
}
}
}

92
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/color_palette.dart

@ -1,92 +0,0 @@
import 'package:flutter/material.dart';
class ColorPalette extends StatefulWidget {
final Color activeColor;
final List<Color> colors;
final Function(Color) onColorPicked;
ColorPalette({
this.activeColor,
this.onColorPicked,
this.colors,
});
@override
_ColorPaletteState createState() => _ColorPaletteState();
}
class _ColorPaletteState extends State<ColorPalette> {
Color _activeColor;
@override
void initState() {
_activeColor = widget.activeColor ?? widget.colors[0];
super.initState();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16),
child: Wrap(
spacing: 16,
runSpacing: 16,
children: widget.colors
.map(
(color) => _ColorHolder(
color: color,
active: color == _activeColor,
onTap: (color) {
setState(() => _activeColor = color);
widget.onColorPicked(color);
},
),
)
.toList(),
),
);
}
}
class _ColorHolder extends StatelessWidget {
final Color color;
final Function(Color) onTap;
final bool active;
_ColorHolder({
this.color,
this.onTap,
this.active = false,
});
@override
Widget build(BuildContext context) {
return Container(
height: 40,
width: 40,
decoration: BoxDecoration(
border: active
? Border.fromBorderSide(
BorderSide(color: Theme.of(context).colorScheme.onSurface))
: null,
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: GestureDetector(
onTap: () => onTap(color),
child: Container(
height: 35,
width: 35,
decoration: BoxDecoration(
border: Border.fromBorderSide(
BorderSide(color: Theme.of(context).colorScheme.onSurface)),
borderRadius: BorderRadius.circular(50),
color: color,
),
),
),
),
);
}
}

30
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/option_button.dart

@ -1,30 +0,0 @@
import 'package:flutter/material.dart';
class OptionButton extends StatelessWidget {
final bool isActive;
final Function() onPressed;
final Widget child;
final Size size;
OptionButton({
this.onPressed,
this.child,
this.isActive = false,
this.size,
});
@override
Widget build(BuildContext context) {
return RawMaterialButton(
constraints: BoxConstraints.tight(size ?? Size(45, 45)),
highlightColor: Theme.of(context).colorScheme.background,
splashColor: Theme.of(context).colorScheme.background,
fillColor: isActive ? Theme.of(context).colorScheme.background : null,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: Theme.of(context).colorScheme.surface),
),
child: child,
onPressed: onPressed,
);
}
}

87
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/toolbar.dart

@ -1,87 +0,0 @@
import 'package:flutter/material.dart';
import 'option_button.dart';
import 'toolbar_action.dart';
class Toolbar extends StatefulWidget {
final EditorToolbarAction initialTool;
final Function(EditorToolbarAction) onToolSelect;
Toolbar({
this.initialTool = EditorToolbarAction.editor,
this.onToolSelect,
});
@override
_ToolbarState createState() => _ToolbarState();
}
class _ToolbarState extends State<Toolbar> {
EditorToolbarAction _selectedAction;
@override
void initState() {
_selectedAction = widget.initialTool;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// OptionButton(
// isActive: _selectedAction == EditorToolbarAction.editor,
// child: Icon(Icons.keyboard),
// onPressed: () {
// setState(() => _selectedAction = EditorToolbarAction.editor);
// widget.onToolSelect(EditorToolbarAction.editor);
// },
// ),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontFamilyTool,
child: Icon(Icons.title),
onPressed: () {
setState(
() => _selectedAction = EditorToolbarAction.fontFamilyTool);
widget.onToolSelect(EditorToolbarAction.fontFamilyTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontOptionTool,
child: Icon(Icons.strikethrough_s),
onPressed: () {
setState(
() => _selectedAction = EditorToolbarAction.fontOptionTool);
widget.onToolSelect(EditorToolbarAction.fontOptionTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontSizeTool,
child: Icon(Icons.format_size),
onPressed: () {
setState(() => _selectedAction = EditorToolbarAction.fontSizeTool);
widget.onToolSelect(EditorToolbarAction.fontSizeTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontColorTool,
child: Icon(Icons.format_color_text),
onPressed: () {
setState(() => _selectedAction = EditorToolbarAction.fontColorTool);
widget.onToolSelect(EditorToolbarAction.fontColorTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.backgroundColorTool,
child: Icon(Icons.format_color_fill),
onPressed: () {
setState(() =>
_selectedAction = EditorToolbarAction.backgroundColorTool);
widget.onToolSelect(EditorToolbarAction.backgroundColorTool);
},
),
],
);
}
}

8
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/toolbar_action.dart

@ -1,8 +0,0 @@
enum EditorToolbarAction {
editor,
fontFamilyTool,
fontOptionTool,
fontSizeTool,
fontColorTool,
backgroundColorTool,
}

24
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/background_color_tool.dart

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
import '../color_palette.dart';
class BackgroundColorTool extends StatelessWidget {
final List<Color> colors;
final Color activeColor;
final Function(Color) onColorPicked;
BackgroundColorTool({
this.colors,
this.onColorPicked,
this.activeColor,
});
@override
Widget build(BuildContext context) {
return ColorPalette(
activeColor: activeColor,
onColorPicked: onColorPicked,
colors: colors,
);
}
}

24
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_color_tool.dart

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
import '../color_palette.dart';
class FontColorTool extends StatelessWidget {
final List<Color> colors;
final Color activeColor;
final Function(Color) onColorPicked;
FontColorTool({
this.colors,
this.onColorPicked,
this.activeColor,
});
@override
Widget build(BuildContext context) {
return ColorPalette(
activeColor: activeColor,
onColorPicked: onColorPicked,
colors: colors,
);
}
}

66
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_family_tool.dart

@ -1,66 +0,0 @@
import 'package:flutter/material.dart';
import '../option_button.dart';
class FontFamilyTool extends StatefulWidget {
final List<String> fonts;
final Function(String) onSelectFont;
final String selectedFont;
FontFamilyTool({
this.fonts,
this.onSelectFont,
this.selectedFont,
});
@override
_FontFamilyToolState createState() => _FontFamilyToolState();
}
class _FontFamilyToolState extends State<FontFamilyTool> {
String _selectedFont;
@override
void initState() {
_selectedFont = widget.selectedFont ?? widget.fonts[0];
super.initState();
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 12,
runSpacing: 12,
children: widget.fonts
.map<_FontFamily>(
(font) => _FontFamily(
font,
isSelected: _selectedFont == font,
onSelect: (selectedFont) {
setState(() => _selectedFont = selectedFont);
widget.onSelectFont(selectedFont);
},
),
)
.toList(),
);
}
}
class _FontFamily extends StatelessWidget {
final String font;
final bool isSelected;
final Function(String) onSelect;
_FontFamily(this.font, {this.onSelect, this.isSelected = false});
@override
Widget build(BuildContext context) {
return OptionButton(
isActive: isSelected,
size: Size(90, 45),
onPressed: () => onSelect(font),
child: Center(child: Text(font, style: TextStyle(fontFamily: font))),
);
}
}

123
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/font_size_tool.dart

@ -1,123 +0,0 @@
import 'package:flutter/material.dart';
class FontSizeTool extends StatelessWidget {
final double fontSize;
final double letterSpacing;
final double letterHeight;
final Function(
double fontSize,
double letterSpacing,
double letterHeight,
) onFontSizeEdited;
FontSizeTool({
this.onFontSizeEdited,
this.fontSize = 0,
this.letterSpacing = 0,
this.letterHeight = 0,
});
@override
Widget build(BuildContext context) {
double _fontSize = fontSize;
double _letterSpacing = letterSpacing;
double _letterHeight = letterHeight;
return Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
_ResizeSlider(
value: _fontSize,
icon: Icons.format_size,
max: 45,
onChange: (value) {
_fontSize = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
_ResizeSlider(
value: _letterHeight,
icon: Icons.format_line_spacing,
max: 10,
onChange: (value) {
_letterHeight = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
_ResizeSlider(
value: _letterSpacing,
icon: Icons.settings_ethernet,
max: 10,
onChange: (value) {
_letterSpacing = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
],
),
);
}
}
class _ResizeSlider extends StatefulWidget {
final double value;
final double min;
final double max;
final IconData icon;
final Function(double) onChange;
_ResizeSlider({
this.value,
this.icon,
this.onChange,
this.min = 0,
this.max = 100,
});
@override
_ResizeSliderState createState() => _ResizeSliderState();
}
class _ResizeSliderState extends State<_ResizeSlider> {
double _value;
@override
void initState() {
_value = widget.value;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Icon(widget.icon),
Expanded(
child: SliderTheme(
data: SliderThemeData(
activeTrackColor: Theme.of(context).colorScheme.background,
inactiveTrackColor: Theme.of(context).colorScheme.background,
thumbColor: Theme.of(context).colorScheme.background,
overlayColor:
Theme.of(context).colorScheme.background.withOpacity(0.2),
trackHeight: 2,
),
child: Slider(
value: _value,
onChanged: (value) {
setState(() => _value = value);
widget.onChange(value);
},
min: widget.min,
max: widget.max,
),
),
),
Text(_value.toStringAsFixed(1)),
],
);
}
}

237
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/src/tools/text_format_tool.dart

@ -1,237 +0,0 @@
import 'package:flutter/material.dart';
import '../option_button.dart';
class TextFormatTool extends StatelessWidget {
final Function(
bool bold,
bool italic,
) onTextFormatEdited;
final Function(bool caps) onCpasLockTaggle;
final Function(TextAlign textAlign) onTextAlignEdited;
final TextAlign textAlign;
final bool bold;
final bool italic;
final bool caps;
TextFormatTool({
this.onTextFormatEdited,
this.onTextAlignEdited,
this.onCpasLockTaggle,
this.textAlign = TextAlign.left,
this.bold = false,
this.italic = false,
this.caps = false,
});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 36),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_TextFormatEditor(
bold: bold,
italic: italic,
caps: caps,
onFormatEdited: onTextFormatEdited,
onCpasLockTaggle: onCpasLockTaggle,
),
SizedBox(height: 36),
_TextAlignEditor(
textAlign: textAlign,
onTextAlignEdited: onTextAlignEdited,
),
],
),
);
}
}
class _TextAlignEditor extends StatefulWidget {
final TextAlign textAlign;
final Function(TextAlign textAlign) onTextAlignEdited;
_TextAlignEditor({
this.onTextAlignEdited,
this.textAlign = TextAlign.left,
});
@override
_TextAlignEditorState createState() => _TextAlignEditorState();
}
class _TextAlignEditorState extends State<_TextAlignEditor> {
TextAlign _textAlign;
@override
void initState() {
_textAlign = widget.textAlign;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_TextAlignOption(
icon: Icons.format_align_left,
isActive: _textAlign == TextAlign.left,
onPressed: () {
setState(() => _textAlign = TextAlign.left);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_center,
isActive: _textAlign == TextAlign.center,
onPressed: () {
setState(() => _textAlign = TextAlign.center);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_right,
isActive: _textAlign == TextAlign.right,
onPressed: () {
setState(() => _textAlign = TextAlign.right);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_justify,
isActive: _textAlign == TextAlign.justify,
onPressed: () {
setState(() => _textAlign = TextAlign.justify);
widget.onTextAlignEdited(_textAlign);
},
),
],
);
}
}
class _TextAlignOption extends StatelessWidget {
final IconData icon;
final Function() onPressed;
final bool isActive;
_TextAlignOption({
this.icon,
this.onPressed,
this.isActive = false,
});
@override
Widget build(BuildContext context) {
return IconButton(
iconSize: 32,
icon: Icon(icon),
color: isActive
? Theme.of(context).iconTheme.color
: Theme.of(context).disabledColor,
onPressed: onPressed,
);
}
}
class _TextFormatEditor extends StatefulWidget {
final Function(bool bold, bool italic) onFormatEdited;
final Function(bool caps) onCpasLockTaggle;
final bool bold;
final bool italic;
final bool caps;
_TextFormatEditor({
this.onFormatEdited,
this.onCpasLockTaggle,
this.bold = false,
this.italic = false,
this.caps = false,
});
@override
_TextFormatEditorState createState() => _TextFormatEditorState();
}
class _TextFormatEditorState extends State<_TextFormatEditor> {
bool _bold;
bool _italic;
bool _caps;
@override
void initState() {
_bold = widget.bold;
_italic = widget.italic;
_caps = widget.caps;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_TextFormatOption(
title: 'BOLD',
icon: Icons.format_bold,
isActive: _bold,
onPressed: () {
setState(() => _bold = !_bold);
widget.onFormatEdited(_bold, _italic);
},
),
_TextFormatOption(
title: 'ITALIC',
icon: Icons.format_italic,
isActive: _italic,
onPressed: () {
setState(() => _italic = !_italic);
widget.onFormatEdited(_bold, _italic);
},
),
_TextFormatOption(
title: 'CAPS',
icon: Icons.keyboard_capslock,
isActive: _caps,
onPressed: () {
setState(() => _caps = !_caps);
widget.onCpasLockTaggle(_caps);
},
),
],
);
}
}
class _TextFormatOption extends StatelessWidget {
final String title;
final IconData icon;
final Function() onPressed;
final bool isActive;
_TextFormatOption({
this.title,
this.icon,
this.onPressed,
this.isActive = false,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
OptionButton(
isActive: isActive,
onPressed: onPressed,
child: Icon(icon),
),
SizedBox(height: 12),
Text(title),
],
);
}
}

223
lib/Pages/Sub_Pages/@Generic/Camera/Video/Editor/textstyler/text_style_editor.dart

@ -1,223 +0,0 @@
library text_style_editor;
export 'src/toolbar_action.dart';
import 'package:flutter/material.dart';
import 'src/toolbar_action.dart';
import 'src/tools/background_color_tool.dart';
import 'src/color_palette.dart';
import 'src/tools/font_family_tool.dart';
import 'src/tools/font_size_tool.dart';
import 'src/tools/text_format_tool.dart';
import 'src/toolbar.dart';
/// Text style editor
/// A flutter widget that edit text style and text alignment
///
/// You can pass your text style or alignment to the widget
/// and then get the edited text style
class TextStyleEditor extends StatefulWidget {
/// Editor's font families
final List<String> fonts;
/// The text style
final TextStyle textStyle;
/// The text alignment
final TextAlign textAlign;
/// The inithial editor tool
final EditorToolbarAction initialTool;
/// Editor's palette colors
final List<Color> paletteColors;
/// [onTextStyleEdited] will be called after [textStyle] prop has changed
final Function(TextStyle) onTextStyleEdited;
/// [onTextAlignEdited] will be called after [textAlingment] prop has changed
final Function(TextAlign) onTextAlignEdited;
/// [onCpasLockTaggle] will be called after caps lock has changed
final Function(bool) onCpasLockTaggle;
/// [onToolbarActionChanged] will be called after editor's tool has changed
final Function(EditorToolbarAction) onToolbarActionChanged;
/// Create a [TextStyleEditor] widget
///
/// [fonts] list of font families that you want to use in editor.
/// [textStyle] initiate text style.
/// [textAlign] initiate text alignment.
///
/// [onTextStyleEdited] callback will be called every time [textStyle] has changed.
/// [onTextAlignEdited] callback will be called every time [textAlign] has changed.
/// [onCpasLockTaggle] callback will be called every time caps lock has changed to off or on.
/// [onToolbarActionChanged] callback will be called every time editor's tool has changed.
TextStyleEditor({
this.fonts,
this.textStyle,
this.textAlign,
this.paletteColors,
this.initialTool = EditorToolbarAction.editor,
this.onTextStyleEdited,
this.onTextAlignEdited,
this.onCpasLockTaggle,
this.onToolbarActionChanged,
});
@override
_TextStyleEditorState createState() => _TextStyleEditorState();
}
class _TextStyleEditorState extends State<TextStyleEditor> {
EditorToolbarAction _currentTool;
TextStyle _textStyle;
TextAlign _textAlign;
List<Color> _paletteColors;
@override
void initState() {
_currentTool = widget.initialTool;
_textStyle = widget.textStyle;
_textAlign = widget.textAlign;
// Set default palette's colors
_paletteColors = widget.paletteColors ??
[
Colors.black,
Colors.white,
Colors.red,
Colors.blue,
Colors.blueAccent,
Colors.brown,
Colors.green,
Colors.indigoAccent,
Colors.lime,
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Toolbar(
initialTool: _currentTool,
onToolSelect: (action) {
setState(() => _currentTool = action);
if (widget.onToolbarActionChanged != null) {
widget.onToolbarActionChanged(action);
}
},
),
Divider(),
Container(
child: SingleChildScrollView(
child: () {
// Choice tools
switch (_currentTool) {
case EditorToolbarAction.fontFamilyTool:
return FontFamilyTool(
fonts: widget.fonts,
selectedFont: _textStyle.fontFamily,
onSelectFont: (fontFamily) {
setState(() => _textStyle =
_textStyle.copyWith(fontFamily: fontFamily));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.fontOptionTool:
return TextFormatTool(
bold: _textStyle.fontWeight == FontWeight.bold,
italic: _textStyle.fontStyle == FontStyle.italic,
textAlign: _textAlign,
onTextFormatEdited: (bold, italic) {
setState(() => _textStyle = _textStyle.copyWith(
fontWeight:
bold ? FontWeight.bold : FontWeight.normal,
fontStyle:
italic ? FontStyle.italic : FontStyle.normal,
));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
onTextAlignEdited: (align) {
setState(() => _textAlign = align);
if (widget.onTextAlignEdited != null) {
widget.onTextAlignEdited(align);
}
},
onCpasLockTaggle: (caps) {
if (widget.onCpasLockTaggle != null) {
widget.onCpasLockTaggle(caps);
}
},
);
case EditorToolbarAction.fontSizeTool:
return FontSizeTool(
fontSize: _textStyle.fontSize ?? 0,
letterHeight: _textStyle.height ?? 1.2,
letterSpacing: _textStyle.letterSpacing ?? 1,
onFontSizeEdited: (
fontSize,
letterSpacing,
letterHeight,
) {
setState(() => _textStyle = _textStyle.copyWith(
fontSize: fontSize,
height: letterHeight,
letterSpacing: letterSpacing,
));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.fontColorTool:
return BackgroundColorTool(
activeColor: _textStyle.color,
colors: _paletteColors,
onColorPicked: (color) {
setState(
() => _textStyle = _textStyle.copyWith(color: color));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.backgroundColorTool:
return ColorPalette(
activeColor: _textStyle.backgroundColor,
colors: _paletteColors,
onColorPicked: (color) {
setState(() => _textStyle =
_textStyle.copyWith(backgroundColor: color));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.editor:
return Container();
default:
return Container();
}
}(),
),
),
],
);
}
}

499
lib/Pages/Sub_Pages/@Generic/Camera/Video/RecordVideo.dart

@ -1,499 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:teso/util/consts.dart';
import 'package:page_transition/page_transition.dart';
import 'dart:async';
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:video_thumbnail/video_thumbnail.dart' as thumb;
import 'Editor/VideoReview.dart';
// ignore: must_be_immutable
class RecordVideo extends StatefulWidget {
List<CameraDescription> connectedCameras;
RecordVideo({Key key, this.connectedCameras}) : super(key: key);
@override
_RecordVideoState createState() => _RecordVideoState();
}
class _RecordVideoState extends State<RecordVideo>
with TickerProviderStateMixin {
CameraController _controller;
int selectedCamera = 0;
bool flash = false;
bool frontFlash = false;
bool recording = false;
AnimationController _recordingAnimationController;
XFile video;
String filePath;
int recordEnd = 60;
CountDownController _controllerCountDown = CountDownController();
final interval = const Duration(seconds: 1);
final picker = ImagePicker();
bool gallery = false;
final int timerMaxSeconds = 60;
int currentSeconds = 0;
flipCamera() {
selectedCamera++;
if (selectedCamera < widget.connectedCameras.length) {
onNewCameraSelected(widget.connectedCameras.elementAt(selectedCamera));
} else {
selectedCamera = 0;
onNewCameraSelected(widget.connectedCameras.elementAt(selectedCamera));
}
}
flashCamera() {
try {
if (!flash &&
_controller.description.lensDirection == CameraLensDirection.back) {
_controller.setFlashMode(FlashMode.torch);
setState(() {
flash = true;
frontFlash = false;
});
} else if (!flash &&
_controller.description.lensDirection == CameraLensDirection.front) {
setState(() {
flash = true;
frontFlash = true;
});
} else if (flash &&
_controller.description.lensDirection == CameraLensDirection.back) {
_controller.setFlashMode(FlashMode.off);
setState(() {
flash = false;
});
} else {
setState(() {
flash = false;
frontFlash = false;
});
}
} catch (e) {}
}
haltRecord() async {
double aspect = _controller.value.aspectRatio;
XFile recorded = await stopVideoRecording();
if (recorded != null)
Navigator.of(context).pushReplacement(
PageRouteBuilder(
opaque: false,
pageBuilder: (_, __, ___) => VideoReview(
video: recorded.path,
aspect: aspect,
// campaignID: widget.campaignID,
recorded: true,
),
),
);
}
Future<Uint8List> generateThumbnail(video) async {
try {
Uint8List thumbnail;
thumbnail = await thumb.VideoThumbnail.thumbnailData(
video: video,
imageFormat: thumb.ImageFormat.JPEG,
maxWidth: 0,
maxHeight: 0,
timeMs: 1,
quality: 100,
);
return thumbnail;
} catch (e) {
print("Error :::: " + e);
return null;
}
}
@override
void initState() {
if (widget.connectedCameras == null ||
widget.connectedCameras.length == 0) {
availableCameras().then((value) {
widget.connectedCameras = value;
onNewCameraSelected(widget.connectedCameras.first);
});
} else {
onNewCameraSelected(widget.connectedCameras.first);
}
_recordingAnimationController =
new AnimationController(vsync: this, duration: Duration(seconds: 1));
_recordingAnimationController.repeat(reverse: true);
super.initState();
}
sayCheese() async {
try {
if (flash && !frontFlash)
await _controller.setFlashMode(FlashMode.always);
await _controller.startVideoRecording();
} catch (e) {
print(e);
}
}
Future<XFile> stopVideoRecording() async {
if (!_controller.value.isRecordingVideo) {
return null;
}
try {
return _controller.stopVideoRecording();
} on CameraException catch (e) {
print(e);
return null;
}
}
void onNewCameraSelected(CameraDescription cameraDescription) async {
if (_controller != null) {
await _controller.dispose();
}
_controller = CameraController(
cameraDescription,
ResolutionPreset.max,
enableAudio: true,
imageFormatGroup: ImageFormatGroup.jpeg,
);
// If the controller is updated then update the UI.
_controller.addListener(() {
if (mounted) setState(() {});
if (_controller.value.hasError) {
print('Camera error ${_controller.value.errorDescription}');
}
});
try {
await _controller.initialize();
_controller.lockCaptureOrientation(DeviceOrientation.portraitUp);
_controller.setFocusMode(FocusMode.auto);
} on CameraException catch (e) {
print(e);
}
if (mounted) {
setState(() {});
}
}
void onHocusFocus(TapDownDetails details, BoxConstraints constraints) {
final offset = Offset(
details.localPosition.dx / constraints.maxWidth,
details.localPosition.dy / constraints.maxHeight,
);
_controller.setExposurePoint(offset);
_controller.setFocusPoint(offset);
}
@override
void dispose() {
_controller?.dispose();
_recordingAnimationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_controller == null || !_controller.value.isInitialized) {
return Container(
color: Colors.black,
);
} else {
return Scaffold(
body: !gallery
? Stack(
children: [
cameraWidget(context),
flashWidget(context),
cameraFlip(context),
cameraFlash(context),
recordingAnimation(context),
recordingCircle(context),
recorderWidget(context),
galleryPicker(context),
],
)
: Container(),
);
}
}
imgFromGallery() async {
try {
setState(() {
gallery = true;
});
final pickedFile = await picker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(minutes: 1),
);
if (pickedFile != null) {
return pickedFile.path;
} else {
onNewCameraSelected(widget.connectedCameras.first);
print('No image selected.');
}
} catch (e) {
print(e);
}
setState(() {
gallery = false;
});
return;
}
Widget recordingCircle(context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: CircularCountDownTimer(
duration: recordEnd,
initialDuration: 0,
controller: _controllerCountDown,
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 2,
ringColor: Colors.grey[300],
fillColor: Colors.red,
backgroundColor: Colors.transparent,
autoStart: false,
strokeWidth: 5.5,
isTimerTextShown: false,
strokeCap: StrokeCap.round,
//onStart: startTimeout,
onComplete: haltRecord,
),
),
);
}
Widget recorderWidget(context) {
return Align(
alignment: Alignment.bottomCenter,
child: InkWell(
onTap: recording
? haltRecord
: () async {
await _controller.startVideoRecording();
setState(() {
_controllerCountDown.start();
recording = !recording;
});
},
child: Container(
margin: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: Icon(
recording ? Icons.stop : Icons.video_camera_back,
color: Colors.white,
size: 25,
),
),
),
);
}
Widget galleryPicker(context) {
return Align(
alignment: Alignment.bottomLeft,
child: recording
? Container()
: InkWell(
onTap: () async {
String result = await imgFromGallery();
if (result != null) {
// _controller.dispose();
Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: VideoReview(
video: result,
recorded: false,
// campaignID: widget.campaignID,
),
));
}
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05,
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: Icon(
Icons.photo,
color: Colors.white,
size: 27,
),
),
),
);
}
Widget recordingAnimation(context) {
if (!recording)
return Align(
alignment: Alignment.topLeft,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.08,
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 35,
width: 35,
decoration: BoxDecoration(
//color: ColorFilterEngineLayer (0, 0, 0, 0.4),
shape: BoxShape.circle),
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
));
else
return Align(
alignment: Alignment.topLeft,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: 5,
vertical: MediaQuery.of(context).size.width * 0.11,
),
padding: EdgeInsets.all(2.5),
height: 20,
width: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.red,
width: 2,
)),
child: FadeTransition(
opacity: _recordingAnimationController,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
),
],
),
),
);
}
Widget cameraFlash(context) {
return !recording
? Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.07,
vertical: MediaQuery.of(context).size.width * 0.25,
),
child: InkWell(
onTap: flashCamera,
child: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: flash ? tesoGold : Colors.white,
size: 30,
),
),
),
)
: Container();
}
Widget cameraFlip(context) {
return !recording
? Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.06,
vertical: MediaQuery.of(context).size.width * 0.11,
),
child: InkWell(
onTap: flipCamera,
child: Icon(
Icons.cameraswitch_outlined,
color: Colors.white,
size: 40,
),
),
),
)
: Container();
}
Widget flashWidget(context) {
return Visibility(
visible: frontFlash,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.4),
),
),
);
}
Widget cameraWidget(context) {
var camera = _controller.value;
final size = MediaQuery.of(context).size;
var scale = size.aspectRatio * camera.aspectRatio;
if (scale < 1) scale = 1 / scale;
return Transform.scale(
scale: scale,
child: Center(
child: CameraPreview(
_controller,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (details) => onHocusFocus(details, constraints),
);
}),
),
),
);
}
}

45
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/file_formats.dart

@ -1,45 +0,0 @@
/// The video file formats available for
/// generating the output trimmed video.
///
/// The available formats are `mp4`, `mkv`,
/// `mov`, `flv`, `avi`, `wmv`& `gif`.
///
/// If you define a custom `FFmpeg` command
/// then this will be ignored.
///
class FileFormat {
const FileFormat._(this.index);
final int index;
static const FileFormat mp4 = FileFormat._(0);
static const FileFormat mkv = FileFormat._(1);
static const FileFormat mov = FileFormat._(2);
static const FileFormat flv = FileFormat._(3);
static const FileFormat avi = FileFormat._(4);
static const FileFormat wmv = FileFormat._(5);
static const FileFormat gif = FileFormat._(6);
static const List<FileFormat> values = <FileFormat>[
mp4,
mkv,
mov,
flv,
avi,
wmv,
gif,
];
@override
String toString() {
return const <int, String>{
0: '.mp4',
1: '.mkv',
2: '.mov',
3: '.flv',
4: '.avi',
5: '.wmv',
6: '.gif',
}[index];
}
}

32
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/storage_dir.dart

@ -1,32 +0,0 @@
/// Supported storage locations.
///
/// * [temporaryDirectory]
///
/// * [applicationDocumentsDirectory]
///
/// * [externalStorageDirectory]
///
class StorageDir {
const StorageDir._(this.index);
final int index;
static const StorageDir temporaryDirectory = StorageDir._(0);
static const StorageDir applicationDocumentsDirectory = StorageDir._(1);
static const StorageDir externalStorageDirectory = StorageDir._(2);
static const List<StorageDir> values = <StorageDir>[
temporaryDirectory,
applicationDocumentsDirectory,
externalStorageDirectory,
];
@override
String toString() {
return const <int, String>{
0: 'temporaryDirectory',
1: 'applicationDocumentsDirectory',
2: 'externalStorageDirectory',
}[index];
}
}

81
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/thumbnail_viewer.dart

@ -1,81 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class ThumbnailViewer extends StatelessWidget {
final videoFile;
final videoDuration;
final thumbnailHeight;
final fit;
final int numberOfThumbnails;
final int quality;
/// For showing the thumbnails generated from the video,
/// like a frame by frame preview
ThumbnailViewer({
@required this.videoFile,
@required this.videoDuration,
@required this.thumbnailHeight,
@required this.numberOfThumbnails,
@required this.fit,
this.quality = 75,
}) : assert(videoFile != null),
assert(videoDuration != null),
assert(thumbnailHeight != null),
assert(numberOfThumbnails != null),
assert(quality != null);
Stream<List<Uint8List>> generateThumbnail() async* {
final String _videoPath = videoFile.path;
double _eachPart = videoDuration / numberOfThumbnails;
List<Uint8List> _byteList = [];
for (int i = 1; i <= numberOfThumbnails; i++) {
Uint8List _bytes;
_bytes = await VideoThumbnail.thumbnailData(
video: _videoPath,
imageFormat: ImageFormat.JPEG,
timeMs: (_eachPart * i).toInt(),
quality: quality,
);
_byteList.add(_bytes);
yield _byteList;
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: generateThumbnail(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Uint8List> _imageBytes = snapshot.data;
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Container(
height: thumbnailHeight,
width: thumbnailHeight,
child: Image(
image: MemoryImage(_imageBytes[index]),
fit: fit,
),
);
});
} else {
return Container(
color: Colors.grey[900],
height: thumbnailHeight,
width: double.maxFinite,
);
}
},
);
}
}

537
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart

@ -1,537 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/thumbnail_viewer.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor_painter.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart';
import 'package:video_player/video_player.dart';
VideoPlayerController videoPlayerController;
class TrimEditor extends StatefulWidget {
/// For defining the total trimmer area width
final double viewerWidth;
/// For defining the total trimmer area height
final double viewerHeight;
/// For defining the image fit type of each thumbnail image.
///
/// By default it is set to `BoxFit.fitHeight`.
final BoxFit fit;
/// For defining the maximum length of the output video.
final Duration maxVideoLength;
/// For specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
///
/// By default it is set to `5.0`.
final double circleSize;
/// For specifying a size to the holder at
/// the two ends of the video trimmer area, while it is being
/// `dragged`.
///
/// By default it is set to `8.0`.
final double circleSizeOnDrag;
/// For specifying a color to the circle.
///
/// By default it is set to `Colors.white`.
final Color circlePaintColor;
/// For specifying a color to the border of
/// the trim area.
///
/// By default it is set to `Colors.white`.
final Color borderPaintColor;
/// For specifying a color to the video
/// scrubber inside the trim area.
///
/// By default it is set to `Colors.white`.
final Color scrubberPaintColor;
/// For specifying the quality of each
/// generated image thumbnail, to be displayed in the trimmer
/// area.
final int thumbnailQuality;
/// For showing the start and the end point of the
/// video on top of the trimmer area.
///
/// By default it is set to `true`.
final bool showDuration;
/// For providing a `TextStyle` to the
/// duration text.
///
/// By default it is set to `TextStyle(color: Colors.white)`
final TextStyle durationTextStyle;
/// Callback to the video start position
///
/// Returns the selected video start position in `milliseconds`.
final Function(double startValue) onChangeStart;
/// Callback to the video end position.
///
/// Returns the selected video end position in `milliseconds`.
final Function(double endValue) onChangeEnd;
/// Callback to the video playback
/// state to know whether it is currently playing or paused.
///
/// Returns a `boolean` value. If `true`, video is currently
/// playing, otherwise paused.
final Function(bool isPlaying) onChangePlaybackState;
/// Widget for displaying the video trimmer.
///
/// This has frame wise preview of the video with a
/// slider for selecting the part of the video to be
/// trimmed.
///
/// The required parameters are [viewerWidth] & [viewerHeight]
///
/// * [viewerWidth] to define the total trimmer area width.
///
///
/// * [viewerHeight] to define the total trimmer area height.
///
///
/// The optional parameters are:
///
/// * [fit] for specifying the image fit type of each thumbnail image.
/// By default it is set to `BoxFit.fitHeight`.
///
///
/// * [maxVideoLength] for specifying the maximum length of the
/// output video.
///
///
/// * [circleSize] for specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `5.0`.
///
///
/// * [circleSizeOnDrag] for specifying a size to the holder at
/// the two ends of the video trimmer area, while it is being
/// `dragged`. By default it is set to `8.0`.
///
///
/// * [circlePaintColor] for specifying a color to the circle.
/// By default it is set to `Colors.white`.
///
///
/// * [borderPaintColor] for specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
///
///
/// * [scrubberPaintColor] for specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
///
///
/// * [thumbnailQuality] for specifying the quality of each
/// generated image thumbnail, to be displayed in the trimmer
/// area.
///
///
/// * [showDuration] for showing the start and the end point of the
/// video on top of the trimmer area. By default it is set to `true`.
///
///
/// * [durationTextStyle] is for providing a `TextStyle` to the
/// duration text. By default it is set to
/// `TextStyle(color: Colors.white)`
///
///
/// * [onChangeStart] is a callback to the video start position.
///
///
/// * [onChangeEnd] is a callback to the video end position.
///
///
/// * [onChangePlaybackState] is a callback to the video playback
/// state to know whether it is currently playing or paused.
///
TrimEditor({
@required this.viewerWidth,
@required this.viewerHeight,
this.fit = BoxFit.fitHeight,
this.maxVideoLength = const Duration(milliseconds: 0),
this.circleSize = 5.0,
this.circleSizeOnDrag = 8.0,
this.circlePaintColor = Colors.white,
this.borderPaintColor = Colors.white,
this.scrubberPaintColor = Colors.white,
this.thumbnailQuality = 75,
this.showDuration = true,
this.durationTextStyle = const TextStyle(
color: Colors.white,
),
this.onChangeStart,
this.onChangeEnd,
this.onChangePlaybackState,
}) : assert(viewerWidth != null),
assert(viewerHeight != null),
assert(fit != null),
assert(maxVideoLength != null),
assert(circleSize != null),
assert(circleSizeOnDrag != null),
assert(circlePaintColor != null),
assert(borderPaintColor != null),
assert(scrubberPaintColor != null),
assert(thumbnailQuality != null),
assert(showDuration != null),
assert(durationTextStyle != null);
@override
_TrimEditorState createState() => _TrimEditorState();
}
class _TrimEditorState extends State<TrimEditor> with TickerProviderStateMixin {
File _videoFile;
double _videoStartPos = 0.0;
double _videoEndPos = 0.0;
bool _canUpdateStart = true;
bool _isLeftDrag = true;
Offset _startPos = Offset(0, 0);
Offset _endPos = Offset(0, 0);
double _startFraction = 0.0;
double _endFraction = 1.0;
int _videoDuration = 0;
int _currentPosition = 0;
double _thumbnailViewerW = 0.0;
double _thumbnailViewerH = 0.0;
int _numberOfThumbnails = 0;
double _circleSize;
double fraction;
double maxLengthPixels;
ThumbnailViewer thumbnailWidget;
Animation<double> _scrubberAnimation;
AnimationController _animationController;
Tween<double> _linearTween;
Future<void> _initializeVideoController() async {
if (_videoFile != null) {
videoPlayerController.addListener(() {
final bool isPlaying = videoPlayerController.value.isPlaying;
if (isPlaying) {
widget.onChangePlaybackState(true);
setState(() {
_currentPosition =
videoPlayerController.value.position.inMilliseconds;
if (_currentPosition > _videoEndPos.toInt()) {
widget.onChangePlaybackState(false);
videoPlayerController.pause();
_animationController.stop();
} else {
if (!_animationController.isAnimating) {
widget.onChangePlaybackState(true);
_animationController.forward();
}
}
});
} else {
if (videoPlayerController.value.isInitialized) {
if (_animationController != null) {
if ((_scrubberAnimation.value).toInt() == (_endPos.dx).toInt()) {
_animationController.reset();
}
_animationController.stop();
widget.onChangePlaybackState(false);
}
}
}
});
videoPlayerController.setVolume(1.0);
_videoDuration = videoPlayerController.value.duration.inMilliseconds;
print(_videoFile.path);
_videoEndPos = fraction != null
? _videoDuration.toDouble() * fraction
: _videoDuration.toDouble();
widget.onChangeEnd(_videoEndPos);
final ThumbnailViewer _thumbnailWidget = ThumbnailViewer(
videoFile: _videoFile,
videoDuration: _videoDuration,
fit: widget.fit,
thumbnailHeight: _thumbnailViewerH,
numberOfThumbnails: _numberOfThumbnails,
quality: widget.thumbnailQuality,
);
thumbnailWidget = _thumbnailWidget;
}
}
void _setVideoStartPosition(DragUpdateDetails details) async {
if (!(_startPos.dx + details.delta.dx < 0) &&
!(_startPos.dx + details.delta.dx > _thumbnailViewerW) &&
!(_startPos.dx + details.delta.dx > _endPos.dx)) {
if (maxLengthPixels != null) {
if (!(_endPos.dx - _startPos.dx - details.delta.dx > maxLengthPixels)) {
setState(() {
if (!(_startPos.dx + details.delta.dx < 0))
_startPos += details.delta;
_startFraction = (_startPos.dx / _thumbnailViewerW);
_videoStartPos = _videoDuration * _startFraction;
widget.onChangeStart(_videoStartPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoStartPos.toInt()));
_linearTween.begin = _startPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
} else {
setState(() {
if (!(_startPos.dx + details.delta.dx < 0))
_startPos += details.delta;
_startFraction = (_startPos.dx / _thumbnailViewerW);
_videoStartPos = _videoDuration * _startFraction;
widget.onChangeStart(_videoStartPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoStartPos.toInt()));
_linearTween.begin = _startPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
}
}
void _setVideoEndPosition(DragUpdateDetails details) async {
if (!(_endPos.dx + details.delta.dx > _thumbnailViewerW) &&
!(_endPos.dx + details.delta.dx < 0) &&
!(_endPos.dx + details.delta.dx < _startPos.dx)) {
if (maxLengthPixels != null) {
if (!(_endPos.dx - _startPos.dx + details.delta.dx > maxLengthPixels)) {
setState(() {
_endPos += details.delta;
_endFraction = _endPos.dx / _thumbnailViewerW;
_videoEndPos = _videoDuration * _endFraction;
widget.onChangeEnd(_videoEndPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoEndPos.toInt()));
_linearTween.end = _endPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
} else {
setState(() {
_endPos += details.delta;
_endFraction = _endPos.dx / _thumbnailViewerW;
_videoEndPos = _videoDuration * _endFraction;
widget.onChangeEnd(_videoEndPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoEndPos.toInt()));
_linearTween.end = _endPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
}
}
@override
void initState() {
super.initState();
_circleSize = widget.circleSize;
_videoFile = Trimmer.currentVideoFile;
_thumbnailViewerH = widget.viewerHeight;
_numberOfThumbnails = widget.viewerWidth ~/ _thumbnailViewerH;
_thumbnailViewerW = _numberOfThumbnails * _thumbnailViewerH;
Duration totalDuration = videoPlayerController.value.duration;
if (widget.maxVideoLength > Duration(milliseconds: 0) &&
widget.maxVideoLength < totalDuration) {
if (widget.maxVideoLength < totalDuration) {
fraction =
widget.maxVideoLength.inMilliseconds / totalDuration.inMilliseconds;
maxLengthPixels = _thumbnailViewerW * fraction;
}
}
_initializeVideoController();
_endPos = Offset(
maxLengthPixels != null ? maxLengthPixels : _thumbnailViewerW,
_thumbnailViewerH,
);
// Defining the tween points
_linearTween = Tween(begin: _startPos.dx, end: _endPos.dx);
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt()),
);
_scrubberAnimation = _linearTween.animate(_animationController)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.stop();
}
});
}
@override
void dispose() {
videoPlayerController.pause();
widget.onChangePlaybackState(false);
if (_videoFile != null) {
videoPlayerController.setVolume(0.0);
videoPlayerController.pause();
videoPlayerController.dispose();
widget.onChangePlaybackState(false);
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onHorizontalDragStart: (DragStartDetails details) {
print("START");
print(details.localPosition);
print((_startPos.dx - details.localPosition.dx).abs());
print((_endPos.dx - details.localPosition.dx).abs());
if (_endPos.dx >= _startPos.dx) {
if ((_startPos.dx - details.localPosition.dx).abs() >
(_endPos.dx - details.localPosition.dx).abs()) {
setState(() {
_canUpdateStart = false;
});
} else {
setState(() {
_canUpdateStart = true;
});
}
} else {
if (_startPos.dx > details.localPosition.dx) {
_isLeftDrag = true;
} else {
_isLeftDrag = false;
}
}
},
onHorizontalDragEnd: (DragEndDetails details) {
setState(() {
_circleSize = widget.circleSize;
});
},
onHorizontalDragUpdate: (DragUpdateDetails details) {
_circleSize = widget.circleSizeOnDrag;
if (_endPos.dx >= _startPos.dx) {
_isLeftDrag = false;
if (_canUpdateStart && _startPos.dx + details.delta.dx > 0) {
_isLeftDrag = false; // To prevent from scrolling over
_setVideoStartPosition(details);
} else if (!_canUpdateStart &&
_endPos.dx + details.delta.dx < _thumbnailViewerW) {
_isLeftDrag = true; // To prevent from scrolling over
_setVideoEndPosition(details);
}
} else {
if (_isLeftDrag && _startPos.dx + details.delta.dx > 0) {
_setVideoStartPosition(details);
} else if (!_isLeftDrag &&
_endPos.dx + details.delta.dx < _thumbnailViewerW) {
_setVideoEndPosition(details);
}
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
widget.showDuration
? Container(
width: _thumbnailViewerW,
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
Duration(milliseconds: _videoStartPos.toInt())
.toString()
.split('.')[0],
style: widget.durationTextStyle,
),
Text(
Duration(milliseconds: _videoEndPos.toInt())
.toString()
.split('.')[0],
style: widget.durationTextStyle,
),
],
),
),
)
: Container(),
CustomPaint(
foregroundPainter: TrimEditorPainter(
startPos: _startPos,
endPos: _endPos,
scrubberAnimationDx: _scrubberAnimation.value,
circleSize: _circleSize,
circlePaintColor: widget.circlePaintColor,
borderPaintColor: widget.borderPaintColor,
scrubberPaintColor: widget.scrubberPaintColor,
),
child: Container(
color: Colors.grey[900],
height: _thumbnailViewerH,
width: _thumbnailViewerW,
child: thumbnailWidget == null ? Column() : thumbnailWidget,
),
),
],
),
);
}
}

150
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor_painter.dart

@ -1,150 +0,0 @@
import 'package:flutter/material.dart';
class TrimEditorPainter extends CustomPainter {
/// To define the start offset
final Offset startPos;
/// To define the end offset
final Offset endPos;
/// To define the horizontal length of the selected video area
final double scrubberAnimationDx;
/// For specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `0.5`.
final double circleSize;
/// For specifying the width of the border around
/// the trim area. By default it is set to `3`.
final double borderWidth;
/// For specifying the width of the video scrubber
final double scrubberWidth;
/// For specifying whether to show the scrubber
final bool showScrubber;
/// For specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
final Color borderPaintColor;
/// For specifying a color to the circle.
/// By default it is set to `Colors.white`
final Color circlePaintColor;
/// For specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
final Color scrubberPaintColor;
/// For drawing the trim editor slider
///
/// The required parameters are [startPos], [endPos]
/// & [scrubberAnimationDx]
///
/// * [startPos] to define the start offset
///
///
/// * [endPos] to define the end offset
///
///
/// * [scrubberAnimationDx] to define the horizontal length of the
/// selected video area
///
///
/// The optional parameters are:
///
/// * [circleSize] for specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `0.5`.
///
///
/// * [borderWidth] for specifying the width of the border around
/// the trim area. By default it is set to `3`.
///
///
/// * [scrubberWidth] for specifying the width of the video scrubber
///
///
/// * [showScrubber] for specifying whether to show the scrubber
///
///
/// * [borderPaintColor] for specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
///
///
/// * [circlePaintColor] for specifying a color to the circle.
/// By default it is set to `Colors.white`.
///
///
/// * [scrubberPaintColor] for specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
///
TrimEditorPainter({
@required this.startPos,
@required this.endPos,
@required this.scrubberAnimationDx,
this.circleSize = 0.5,
this.borderWidth = 3,
this.scrubberWidth = 1,
this.showScrubber = true,
this.borderPaintColor = Colors.white,
this.circlePaintColor = Colors.white,
this.scrubberPaintColor = Colors.white,
}) : assert(startPos != null),
assert(endPos != null),
assert(scrubberAnimationDx != null),
assert(circleSize != null),
assert(borderWidth != null),
assert(scrubberWidth != null),
assert(showScrubber != null),
assert(borderPaintColor != null),
assert(circlePaintColor != null),
assert(scrubberPaintColor != null);
@override
void paint(Canvas canvas, Size size) {
var borderPaint = Paint()
..color = borderPaintColor
..strokeWidth = borderWidth
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
var circlePaint = Paint()
..color = circlePaintColor
..strokeWidth = 1
..style = PaintingStyle.fill
..strokeCap = StrokeCap.round;
var scrubberPaint = Paint()
..color = scrubberPaintColor
..strokeWidth = scrubberWidth
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
final rect = Rect.fromPoints(startPos, endPos);
if (showScrubber) {
if (scrubberAnimationDx.toInt() > startPos.dx.toInt()) {
canvas.drawLine(
Offset(scrubberAnimationDx, 0),
Offset(scrubberAnimationDx, 0) + Offset(0, endPos.dy),
scrubberPaint,
);
}
}
canvas.drawRect(rect, borderPaint);
canvas.drawCircle(
startPos + Offset(0, endPos.dy / 2), circleSize, circlePaint);
canvas.drawCircle(
endPos + Offset(0, -endPos.dy / 2), circleSize, circlePaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

300
lib/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart

@ -1,300 +0,0 @@
import 'dart:io';
import 'package:path/path.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/file_formats.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/storage_dir.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart';
import 'package:video_player/video_player.dart';
/// Helps in loading video from file, saving trimmed video to a file
/// and gives video playback controls. Some of the helpful methods
/// are:
/// * [loadVideo()]
/// * [saveTrimmedVideo()]
/// * [videPlaybackControl()]
class Trimmer {
static File currentVideoFile;
final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
/// Loads a video using the path provided.
///
/// Returns the loaded video file.
Future<void> loadVideo({@required File videoFile}) async {
currentVideoFile = videoFile;
if (currentVideoFile != null) {
videoPlayerController = VideoPlayerController.file(currentVideoFile);
await videoPlayerController.initialize().then((_) {
TrimEditor(
viewerHeight: 50,
viewerWidth: 50.0 * 8,
// currentVideoFile: currentVideoFile,
);
});
// TrimEditor(
// viewerHeight: 50,
// viewerWidth: 50.0 * 8,
// // currentVideoFile: currentVideoFile,
// );
}
}
Future<String> _createFolderInAppDocDir(
String folderName,
StorageDir storageDir,
) async {
Directory _directory;
if (storageDir == null) {
_directory = await getApplicationDocumentsDirectory();
} else {
switch (storageDir.toString()) {
case 'temporaryDirectory':
_directory = await getTemporaryDirectory();
break;
case 'applicationDocumentsDirectory':
_directory = await getApplicationDocumentsDirectory();
break;
case 'externalStorageDirectory':
_directory = await getExternalStorageDirectory();
break;
}
}
// Directory + folder name
final Directory _directoryFolder =
Directory('${_directory.path}/$folderName/');
if (await _directoryFolder.exists()) {
// If folder already exists return path
print('Exists');
return _directoryFolder.path;
} else {
print('Creating');
// If folder does not exists create folder and then return its path
final Directory _directoryNewFolder =
await _directoryFolder.create(recursive: true);
return _directoryNewFolder.path;
}
}
/// Saves the trimmed video to file system.
///
/// Returns the output video path
///
/// The required parameters are [startValue] & [endValue].
///
/// The optional parameters are [videoFolderName], [videoFileName],
/// [outputFormat], [fpsGIF], [scaleGIF], [applyVideoEncoding].
///
/// The `@required` parameter [startValue] is for providing a starting point
/// to the trimmed video. To be specified in `milliseconds`.
///
/// The `@required` parameter [endValue] is for providing an ending point
/// to the trimmed video. To be specified in `milliseconds`.
///
/// The parameter [videoFolderName] is used to
/// pass a folder name which will be used for creating a new
/// folder in the selected directory. The default value for
/// it is `Trimmer`.
///
/// The parameter [videoFileName] is used for giving
/// a new name to the trimmed video file. By default the
/// trimmed video is named as `<original_file_name>_trimmed.mp4`.
///
/// The parameter [outputFormat] is used for providing a
/// file format to the trimmed video. This only accepts value
/// of [FileFormat] type. By default it is set to `FileFormat.mp4`,
/// which is for `mp4` files.
///
/// The parameter [storageDir] can be used for providing a storage
/// location option. It accepts only [StorageDir] values. By default
/// it is set to [applicationDocumentsDirectory]. Some of the
/// storage types are:
///
/// * [temporaryDirectory] (Only accessible from inside the app, can be
/// cleared at anytime)
///
/// * [applicationDocumentsDirectory] (Only accessible from inside the app)
///
/// * [externalStorageDirectory] (Supports only `Android`, accessible externally)
///
/// The parameters [fpsGIF] & [scaleGIF] are used only if the
/// selected output format is `FileFormat.gif`.
///
/// * [fpsGIF] for providing a FPS value (by default it is set
/// to `10`)
///
///
/// * [scaleGIF] for proving a width to output GIF, the height
/// is selected by maintaining the aspect ratio automatically (by
/// default it is set to `480`)
///
///
/// * [applyVideoEncoding] for specifying whether to apply video
/// encoding (by default it is set to `false`).
///
///
/// ADVANCED OPTION:
///
/// If you want to give custom `FFmpeg` command, then define
/// [ffmpegCommand] & [customVideoFormat] strings. The `input path`,
/// `output path`, `start` and `end` position is already define.
///
/// NOTE: The advanced option does not provide any safety check, so if wrong
/// video format is passed in [customVideoFormat], then the app may
/// crash.
///
Future<String> saveTrimmedVideo({
@required double startValue,
@required double endValue,
bool applyVideoEncoding = false,
FileFormat outputFormat,
String ffmpegCommand,
String customVideoFormat,
int fpsGIF,
int scaleGIF,
String videoFolderName,
String videoFileName,
StorageDir storageDir,
}) async {
final String _videoPath = currentVideoFile.path;
final String _videoName = basename(_videoPath).split('.')[0];
String _command;
// Formatting Date and Time
String dateTime = DateFormat.yMMMd()
.addPattern('-')
.add_Hms()
.format(DateTime.now())
.toString();
// String _resultString;
String _outputPath;
String _outputFormatString;
String formattedDateTime = dateTime.replaceAll(' ', '');
print("DateTime: $dateTime");
print("Formatted: $formattedDateTime");
if (videoFolderName == null) {
videoFolderName = "Trimmer";
}
if (videoFileName == null) {
videoFileName = "${_videoName}_trimmed:$formattedDateTime";
}
videoFileName = videoFileName.replaceAll(' ', '_');
String path = await _createFolderInAppDocDir(
videoFolderName,
storageDir,
).whenComplete(
() => print("Retrieved Trimmer folder"),
);
Duration startPoint = Duration(milliseconds: startValue.toInt());
Duration endPoint = Duration(milliseconds: endValue.toInt());
// Checking the start and end point strings
print("Start: ${startPoint.toString()} & End: ${endPoint.toString()}");
print(path);
if (outputFormat == null) {
if (Platform.isIOS) {
outputFormat = FileFormat.mp4;
} else {
outputFormat = FileFormat.mkv;
}
_outputFormatString = outputFormat.toString();
print('OUTPUT: $_outputFormatString');
} else {
_outputFormatString = outputFormat.toString();
}
String _trimLengthCommand =
' -ss $startPoint -i "$_videoPath" -t ${endPoint - startPoint} -avoid_negative_ts make_zero ';
if (ffmpegCommand == null) {
_command = '$_trimLengthCommand -c:a copy ';
if (!applyVideoEncoding) {
_command += '-c:v copy ';
}
if (outputFormat == FileFormat.gif) {
if (fpsGIF == null) {
fpsGIF = 10;
}
if (scaleGIF == null) {
scaleGIF = 480;
}
_command =
'$_trimLengthCommand -vf "fps=$fpsGIF,scale=$scaleGIF:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ';
}
} else {
_command = '$_trimLengthCommand $ffmpegCommand ';
_outputFormatString = customVideoFormat;
}
_outputPath = '$path$videoFileName$_outputFormatString';
_command += '"$_outputPath"';
print(_command);
await _flutterFFmpeg.execute(_command).whenComplete(() {
print('Got value');
debugPrint('Video successfuly saved');
// _resultString = 'Video successfuly saved';
}).catchError((error) {
print('Error');
// _resultString = 'Couldn\'t save the video';
debugPrint('Couldn\'t save the video');
});
return _outputPath;
}
/// For getting the video controller state, to know whether the
/// video is playing or paused currently.
///
/// The two required parameters are [startValue] & [endValue]
///
/// * [startValue] is the current starting point of the video.
/// * [endValue] is the current ending point of the video.
///
/// Returns a `Future<bool>`, if `true` then video is playing
/// otherwise paused.
Future<bool> videPlaybackControl({
@required double startValue,
@required double endValue,
}) async {
if (videoPlayerController.value.isPlaying) {
await videoPlayerController.pause();
return false;
} else {
if (videoPlayerController.value.position.inMilliseconds >=
endValue.toInt()) {
await videoPlayerController
.seekTo(Duration(milliseconds: startValue.toInt()));
await videoPlayerController.play();
return true;
} else {
await videoPlayerController.play();
return true;
}
}
}
File getVideoFile() {
return currentVideoFile;
}
}

1
lib/Pages/Sub_Pages/AccountSettings/newPassword.dart

@ -7,7 +7,6 @@ import 'package:teso/util/consts.dart';
import 'dart:math' as math;
import 'package:teso/Pages/PageWidgets/Login/validation.dart';
import 'dart:convert';
import 'dart:ui';
class CreateNewPassword extends StatefulWidget {
@override

153
lib/Pages/Sub_Pages/Campaign/AuditionPage.dart

@ -1,153 +0,0 @@
import 'package:flutter/material.dart';
import 'package:teso/Classes/API%20Clasess/Campaign.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/RecordVideo.dart';
import 'package:teso/providers/pageAnimations.dart';
import 'package:teso/util/consts.dart';
class Audition extends StatefulWidget {
final Campaign campaign;
const Audition({Key key, this.campaign}) : super(key: key);
@override
_AuditionState createState() => _AuditionState();
}
class _AuditionState extends State<Audition> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.campaign.title,
),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
scrollDirection: Axis.vertical,
children: [
Container(
width: MediaQuery.of(context).size.width,
height: 150,
child: Center(
child: Container(
width: 150,
height: 150,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 0.5,
),
borderRadius: BorderRadius.only(
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
child: Image(
width: MediaQuery.of(context).size.width * 0.28,
height: 110,
fit: BoxFit.fill,
image: NetworkImage(widget.campaign.targetProduct != null
? productURL + widget.campaign.targetProduct
: ""),
),
),
),
),
),
SizedBox(
height: 20,
),
Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: "Publisher : ",
style: new TextStyle(
fontWeight: FontWeight.bold,
),
),
new TextSpan(
text: widget.campaign.businessID,
),
],
),
),
),
),
SizedBox(
height: 10,
),
Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
"Description",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.5,
),
),
),
),
Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(widget.campaign.description),
),
),
SizedBox(
height: 30,
),
Container(
width: double.infinity,
child: Align(
alignment: Alignment.center,
child: Container(
width: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
),
primary: accentMain,
),
onPressed: () => Navigator.pushReplacement(
context,
PageTransition(
child: RecordVideo(
campaignID: widget.campaign.campaignID,
),
type: PageTransitionType.fade,
),
),
child: Text("Submit Ad"),
),
),
),
),
],
),
),
);
}
}

200
lib/Pages/Sub_Pages/Campaign/CreatePost.dart

@ -1,200 +0,0 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:http/http.dart' as http;
class CreateCampaignPost extends StatefulWidget {
final String video;
final Uint8List thumbnail;
final String campaignID;
final String aspectRatio;
const CreateCampaignPost({
Key key,
this.video,
this.thumbnail,
this.campaignID,
this.aspectRatio,
}) : super(key: key);
@override
_CreateCampaignPostState createState() => _CreateCampaignPostState();
}
class _CreateCampaignPostState extends State<CreateCampaignPost> {
String aspectRatio;
TextEditingController controller;
SharedPreferences prefs;
bool sending = false;
void postVideo(context) async {
setState(() {
sending = true;
});
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("tokensTeso");
Map<String, String> requestHeaders = {'Authorization': token};
String urlLocation = tesoStreaming + "api/mobile/upload/authurl";
var client =
await http.get(Uri.parse(urlLocation), headers: requestHeaders);
if (client.statusCode == 200) {
var details = jsonDecode(client.body);
String muxuploadsID = details["data"]["id"];
String muxuploadsURL = details["data"]["url"];
Provider.of<UserProvider>(context, listen: false).uploadPost(Uploading(
id: DateTime.now().toString() +
widget.video.replaceAll("file://", ""),
aspect: widget.aspectRatio,
path: widget.video.replaceAll("file://", ""),
thumbnail:
widget.thumbnail != null ? base64Encode(widget.thumbnail) : null,
title: controller.text,
pending: 0,
campaignID: widget.campaignID,
muxuploadID: muxuploadsID,
muxuploadURL: muxuploadsURL,
));
Navigator.pop(context);
}
} catch (e) {
print(e);
}
setState(() {
sending = false;
});
}
@override
void initState() {
super.initState();
controller = new TextEditingController();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
child: AppBar(
automaticallyImplyLeading: true,
title: Text("Post"),
centerTitle: true,
),
preferredSize: Size.fromHeight(70.0),
),
body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.025),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.25,
height: MediaQuery.of(context).size.width * 0.35,
color: Colors.black,
child: widget.thumbnail != null
? Image.memory(widget.thumbnail)
: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
Container(
width: (MediaQuery.of(context).size.width) -
(MediaQuery.of(context).size.width * 0.35),
height: MediaQuery.of(context).size.width * 0.35,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide.none,
),
filled: true,
isDense: true,
labelText: "Say Something..",
labelStyle: TextStyle(
color: Colors.black54,
),
fillColor: Colors.white70,
),
controller: controller,
maxLines: null,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
),
),
],
),
),
SizedBox(
height: 20,
),
Divider(),
Container(
margin: EdgeInsets.only(
top: 10,
),
child: Text(
"Teso businesses and other Teso users can see your post in their feeds and on your profile.",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey,
),
),
),
],
),
),
),
floatingActionButton: !sending
? Container(
margin: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: tesoBlue,
),
child: InkWell(
onTap: () => postVideo(context),
child: Center(
child: Text(
"NEXT",
style: TextStyle(
color: Colors.white,
),
),
),
),
height: 50,
)
: Container(
width: MediaQuery.of(context).size.width,
height: 50,
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

195
lib/Pages/Sub_Pages/Campaign/SubmitAdvert.dart

@ -1,195 +0,0 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:http/http.dart' as http;
class SubmitAdvert extends StatefulWidget {
final String video;
final String aspectRatio;
final Uint8List thumbnail;
final String campaignID;
const SubmitAdvert(
{Key key, this.video, this.aspectRatio, this.thumbnail, this.campaignID})
: super(key: key);
@override
_SubmitAdvertState createState() => _SubmitAdvertState();
}
class _SubmitAdvertState extends State<SubmitAdvert> {
TextEditingController controller;
SharedPreferences prefs;
bool sending = false;
void postVideo(context) async {
setState(() {
sending = true;
});
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("tokensTeso");
Map<String, String> requestHeaders = {'Authorization': token};
String urlLocation = tesoStreaming + "api/mobile/upload/authurl";
var client =
await http.get(Uri.parse(urlLocation), headers: requestHeaders);
if (client.statusCode == 200) {
var details = jsonDecode(client.body);
String muxuploadsID = details["data"]["id"];
String muxuploadsURL = details["data"]["url"];
Provider.of<UserProvider>(context, listen: false).uploadPost(Uploading(
id: DateTime.now().toString() +
widget.video.replaceAll("file://", ""),
aspect: widget.aspectRatio,
path: widget.video.replaceAll("file://", ""),
thumbnail:
widget.thumbnail != null ? base64Encode(widget.thumbnail) : null,
title: controller.text,
pending: 0,
campaignID: widget.campaignID,
muxuploadID: muxuploadsID,
muxuploadURL: muxuploadsURL,
));
Navigator.pop(context);
}
} catch (e) {
print("Something is " + e.toString());
}
setState(() {
sending = false;
});
}
@override
void initState() {
super.initState();
controller = new TextEditingController();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
child: AppBar(
automaticallyImplyLeading: true,
title: Text("Post"),
centerTitle: true,
),
preferredSize: Size.fromHeight(70.0),
),
body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.025),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.25,
height: MediaQuery.of(context).size.width * 0.35,
color: Colors.black,
child: widget.thumbnail != null
? Image.memory(widget.thumbnail)
: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
Container(
width: (MediaQuery.of(context).size.width) -
(MediaQuery.of(context).size.width * 0.35),
height: MediaQuery.of(context).size.width * 0.35,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide.none,
),
filled: true,
isDense: true,
labelText: "Say Something..",
labelStyle: TextStyle(
color: Colors.black54,
),
fillColor: Colors.white70,
),
controller: controller,
maxLines: null,
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
),
),
],
),
),
SizedBox(
height: 20,
),
Divider(),
Container(
margin: EdgeInsets.only(
top: 10,
),
child: Text(
"Teso businesses and other Teso users can only see campaign post on your profile after they have been approved by the campaign owners.",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey,
),
),
),
],
),
),
),
floatingActionButton: !sending
? Container(
margin: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: tesoBlue,
),
child: InkWell(
onTap: () => postVideo(context),
child: Center(
child: Text(
"NEXT",
style: TextStyle(
color: Colors.white,
),
),
),
),
height: 50,
)
: Container(
width: MediaQuery.of(context).size.width,
height: 50,
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

212
lib/Pages/Sub_Pages/Campaign/Video/Editor/TextEditor.dart

@ -1,212 +0,0 @@
// import 'package:flutter/material.dart';
// import 'package:teso/Classes/TextE.dart';
// import 'package:teso/util/SizeConfig.dart';
// import 'textstyler/src/toolbar_action.dart';
// import 'textstyler/text_style_editor.dart';
// // ignore: must_be_immutable
// class TextEdit extends StatefulWidget {
// Textted content;
// TextEdit({Key key, this.content}) : super(key: key);
// @override
// _TextEditState createState() => _TextEditState();
// }
// class _TextEditState extends State<TextEdit> {
// TextStyle textStyle;
// TextAlign textAlign;
// List<String> fonts = [
// 'Billabong',
// 'AlexBrush',
// 'Allura',
// 'Arizonia',
// 'ChunkFive',
// 'GrandHotel',
// 'GreatVibes',
// 'Lobster',
// 'OpenSans',
// 'OstrichSans',
// 'Oswald',
// 'Pacifico',
// 'Quicksand',
// 'Roboto',
// 'SEASRN',
// 'Windsong',
// ];
// List<Color> paletteColors = [
// Colors.black,
// Colors.white,
// Color(int.parse('0xffEA2027')),
// Color(int.parse('0xff006266')),
// Color(int.parse('0xff1B1464')),
// Color(int.parse('0xff5758BB')),
// Color(int.parse('0xff6F1E51')),
// Color(int.parse('0xffB53471')),
// Color(int.parse('0xffEE5A24')),
// Color(int.parse('0xff009432')),
// Color(int.parse('0xff0652DD')),
// Color(int.parse('0xff9980FA')),
// Color(int.parse('0xff833471')),
// Color(int.parse('0xff112CBC4')),
// Color(int.parse('0xffFDA7DF')),
// Color(int.parse('0xffED4C67')),
// Color(int.parse('0xffF79F1F')),
// Color(int.parse('0xffA3CB38')),
// Color(int.parse('0xff1289A7')),
// Color(int.parse('0xffD980FA'))
// ];
// FocusNode _focus = new FocusNode();
// TextEditingController controller;
// @override
// void initState() {
// controller = new TextEditingController();
// textStyle = TextStyle(
// fontSize: 15,
// color: Colors.white,
// fontFamily: 'OpenSans',
// );
// textAlign = TextAlign.left;
// _focus.addListener(_onFocusChange);
// controller.text = widget.content.text != null ? widget.content.text : "";
// textStyle =
// widget.content.textStyle != null ? widget.content.textStyle : null;
// textAlign = widget.content.textAlign != null
// ? widget.content.textAlign
// : TextAlign.center;
// super.initState();
// }
// @override
// void dispose() {
// _focus.removeListener(_onFocusChange);
// _focus.dispose();
// super.dispose();
// }
// void _onFocusChange() {
// debugPrint("Focus: " + _focus.hasFocus.toString());
// }
// void verify() {
// if (_focus.hasFocus) {
// _focus.unfocus();
// } else {
// Navigator.pop(
// context,
// new Textted(
// text: controller.text,
// textAlign: textAlign,
// textStyle: textStyle,
// ));
// }
// }
// @override
// Widget build(BuildContext context) {
// SizeConfig().init(context);
// return Scaffold(
// resizeToAvoidBottomInset: false,
// backgroundColor: Color.fromRGBO(0, 0, 0, 0.8),
// appBar: AppBar(
// backgroundColor: Colors.transparent,
// leading: IconButton(
// onPressed: () => Navigator.pop(context, widget.content),
// icon: Icon(
// Icons.x,
// color: Colors.white,
// ),
// ),
// actions: [
// IconButton(
// onPressed: verify,
// icon: Icon(
// AntDesign.check,
// color: Colors.white,
// ),
// ),
// ],
// ),
// body: Container(
// height: SizeConfig.safeBlockVertical * 40,
// child: Center(
// child: TextField(
// controller: controller,
// // enabled: false,
// focusNode: _focus,
// style: textStyle,
// textAlign: textAlign,
// // maxLines: 4,
// decoration: new InputDecoration(
// filled: true,
// enabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(10.0),
// ),
// borderSide: BorderSide(
// color: Colors.grey.shade400,
// width: 2,
// ),
// ),
// focusedBorder: OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(10.0),
// ),
// borderSide: BorderSide(
// color: Colors.blue.shade300,
// width: 0,
// ),
// ),
// contentPadding: EdgeInsets.all(15),
// ),
// ),
// ),
// ),
// extendBody: false,
// extendBodyBehindAppBar: false,
// bottomSheet: Container(
// height: SizeConfig.safeBlockVertical * 60,
// child: Container(
// padding: EdgeInsets.all(10),
// decoration: BoxDecoration(
// color: Theme.of(context).backgroundColor,
// border: Border.symmetric(
// horizontal: BorderSide(
// color: Theme.of(context).backgroundColor,
// ),
// ),
// ),
// child: Align(
// alignment: Alignment.topCenter,
// child: SingleChildScrollView(
// scrollDirection: Axis.vertical,
// child: TextStyleEditor(
// fonts: fonts,
// paletteColors: paletteColors,
// textStyle: textStyle,
// textAlign: textAlign,
// initialTool: EditorToolbarAction.fontFamilyTool,
// onTextAlignEdited: (align) {
// setState(() {
// textAlign = align;
// });
// },
// onTextStyleEdited: (style) {
// setState(() {
// textStyle = textStyle.merge(style);
// });
// },
// onCpasLockTaggle: (caps) {
// print(caps);
// },
// //onToolbarActionChanged: (fu) => ,
// ),
// ),
// ),
// ),
// ),
// );
// }
// }

560
lib/Pages/Sub_Pages/Campaign/Video/Editor/VideoReview.dart

@ -1,560 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share_plus/share_plus.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/file_formats.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trim_editor.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/Trimmer/trimmer.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/SubmitAdvert.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:video_player/video_player.dart';
import 'package:teso/util/consts.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:provider/provider.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:image/image.dart' as IMG;
import 'package:video_thumbnail/video_thumbnail.dart';
class VideoReview extends StatefulWidget {
final video;
final bool recorded;
final String campaignID;
final double aspect;
@override
const VideoReview(
{Key key,
this.video,
@required this.campaignID,
@required this.recorded,
this.aspect})
: super(key: key);
@override
_VideoReviewState createState() => _VideoReviewState();
}
class _VideoReviewState extends State<VideoReview>
with TickerProviderStateMixin {
Trimmer _trimmer = new Trimmer();
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
bool muted = false;
String readyVideo;
Color textColor = Colors.white;
double _startValue = 0.15;
double _endValue = 60000.0;
var _future;
bool _isPlaying = false;
Duration _duration;
Duration _position;
ByteData bytes;
Uint8List imageBitmap;
Uint8List thumbnail;
Directory tempDirectory;
TesoUser user;
bool processing = false;
bool downloaded = false;
bool processed = false;
final key = new GlobalKey();
double currentOffset = 0;
Future<void> _startVideoPlayer() async {
await videoController.play();
}
Future<void> initializeController(String fileLocation) async {
videoController = VideoPlayerController.file(File(fileLocation));
videoPlayerListener = () async {
Timer.run(() {
this.setState(() {
_position = videoController.value.position;
});
setState(() {
_duration = Duration(milliseconds: _endValue.round());
});
if (_duration?.compareTo(_position) == 0 ||
_duration?.compareTo(_position) == -1) {
this.setState(() {
_isPlaying = false;
});
videoController.pause();
videoController.seekTo(Duration(milliseconds: _startValue.round()));
} else {}
});
};
videoController.addListener(videoPlayerListener);
await videoController.setLooping(true);
await videoController.initialize();
await _trimmer.loadVideo(videoFile: File(fileLocation));
}
@override
void initState() {
readyVideo = widget.video;
if (readyVideo != null) _future = initializeController(readyVideo);
rootBundle.load("assets/images/rawLogo.png").then((value) => setState(() {
imageBitmap = value.buffer.asUint8List();
IMG.Image img = IMG.decodeImage(imageBitmap);
IMG.Image resized = IMG.copyResize(img, width: 50, height: 60);
imageBitmap = IMG.encodePng(resized);
}));
super.initState();
}
@override
void dispose() {
videoController?.dispose();
super.dispose();
}
void postVideo(context) async {
setState(() {
processing = true;
});
if (processed) {
await Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: SubmitAdvert(
video: readyVideo,
aspectRatio: widget.recorded
? "0.5625"
: videoController.value.aspectRatio.toString(),
thumbnail: this.thumbnail,
campaignID: widget.campaignID,
),
));
} else {
readyVideo = await processVideo(context, false);
await Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: SubmitAdvert(
video: readyVideo,
aspectRatio: widget.recorded
? "0.5625"
: videoController.value.aspectRatio.toString(),
thumbnail: this.thumbnail,
campaignID: widget.campaignID,
),
));
}
}
Future<void> downloadVideo(context) async {
try {
setState(() {
processing = true;
});
String output = await processVideo(context, true);
await ImageGallerySaver.saveFile(output).catchError((error, stackTrace) {
setState(() {
processing = false;
downloaded = false;
});
}).then((value) {
setState(() {
processing = false;
downloaded = true;
});
});
} catch (e) {
print(e);
}
}
Future<String> processVideo(context, bool watermark) async {
user = Provider.of<UserProvider>(context, listen: false).currentUser;
String location = await getTemporaryDirectory().then((value) =>
value.path +
"/" +
DateTime.now().millisecondsSinceEpoch.toString() +
".mp4");
if (widget.recorded) {
String initial = await _trimmer.saveTrimmedVideo(
applyVideoEncoding: false,
ffmpegCommand: "-vf setsar=1:1 -aspect 9:16",
customVideoFormat: ".mp4",
startValue: _startValue,
endValue: videoController.value.duration.inMilliseconds > 5900 &&
videoController.value.duration.inMilliseconds >= _endValue
? _endValue
: double.parse(
videoController.value.duration.inMilliseconds.toString()),
);
this.thumbnail = await generateThumbnail();
location = initial;
} else {
String initial = await _trimmer.saveTrimmedVideo(
startValue: _startValue,
endValue: videoController.value.duration.inMilliseconds > 5900 &&
videoController.value.duration.inMilliseconds >= _endValue
? _endValue
: double.parse(
videoController.value.duration.inMilliseconds.toString()),
outputFormat: FileFormat.mp4,
);
this.thumbnail = await generateThumbnail();
location = initial;
}
return location;
}
Future<Uint8List> generateThumbnail() async {
try {
Uint8List thumbnail;
thumbnail = await VideoThumbnail.thumbnailData(
video: widget.video,
imageFormat: ImageFormat.JPEG,
maxWidth: 0,
maxHeight: 0,
timeMs: 100,
quality: 100,
);
return thumbnail;
} catch (e) {
print("Error :::: " + e);
return null;
}
}
Future<void> shareVideo(context) async {
setState(() {
processing = true;
});
if (readyVideo == widget.video) {
readyVideo = await processVideo(context, true);
Share.shareFiles([readyVideo]);
} else {
Share.shareFiles([readyVideo]);
}
setState(() {
processing = false;
});
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container(
color: Colors.black,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.red,
),
),
);
} else {
return Stack(
children: [
videoContent(context),
// Video trimmer
trimmerWidget(context),
// Pop button
Align(
alignment: Alignment.topLeft,
child: InkWell(
onTap: () => Navigator.pop(context),
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.07,
vertical: MediaQuery.of(context).size.width * 0.1,
),
height: 35,
width: 35,
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.4),
shape: BoxShape.circle),
child: Icon(
Icons.close,
color: Colors.white,
size: 20,
),
),
),
),
// Bottom buttons
bottomButtons(context),
Visibility(
visible: processing,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Color.fromRGBO(0, 0, 0, 0.6),
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width * 0.7),
child: Center(
child: Column(
children: [
CupertinoActivityIndicator(
animating: true,
radius: 15,
),
Text(
"Processing.....",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
),
),
],
);
}
}),
);
}
Widget trimmerWidget(context) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.01,
vertical: MediaQuery.of(context).size.width * 0.20,
),
width: MediaQuery.of(context).size.width,
child: TrimEditor(
borderPaintColor: tesoGold,
circlePaintColor: tesoBlue,
thumbnailQuality: 100,
showDuration: true,
viewerHeight: 50.0,
maxVideoLength: Duration(seconds: 60),
viewerWidth: MediaQuery.of(context).size.width,
onChangeStart: (value) {
if (!mounted) {
setState(() {
_startValue = value;
});
} else {
_startValue = value;
}
videoController.seekTo(Duration(milliseconds: value.round()));
},
onChangeEnd: (value) {
if (!mounted) {
setState(() {
_endValue = value;
});
} else {
_endValue = value;
}
},
onChangePlaybackState: (isPlaying) {
if (mounted)
setState(() {
_isPlaying = isPlaying;
});
},
));
}
Widget videoContent(context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Center(
child: AspectRatio(
aspectRatio: videoController.value.size != null
? videoController.value.aspectRatio
: 1.0,
child: Stack(
children: [
InkWell(
onTap: () {
!_isPlaying ? _startVideoPlayer() : videoController.pause();
setState(() {
_isPlaying = !_isPlaying;
});
},
child: VideoPlayer(
videoController,
),
),
Container(
width: double.infinity,
height: double.infinity,
child: GestureDetector(
child: !_isPlaying
? Icon(
Icons.play_circle,
size: 60,
color: Colors.white,
)
: Container(),
onTap: () {
!_isPlaying
? _startVideoPlayer()
: videoController.pause();
setState(() {
_isPlaying = !_isPlaying;
});
},
),
),
],
)),
),
);
}
Widget bottomButtons(context) {
if (widget.recorded) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05,
vertical: SizeConfig.safeBlockVertical * 2.5,
),
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 55,
height: 40,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.6),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
border: Border.all(color: Colors.white, width: 0.5)),
child: InkWell(
onTap: () async =>
!downloaded ? await downloadVideo(context) : null,
child: Icon(
!downloaded ? Icons.download : Icons.check,
color: !downloaded ? Colors.white : Colors.green,
),
),
),
Container(
width: 55,
height: 40,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.6),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
border: Border.all(color: Colors.white, width: 0.5)),
child: InkWell(
onTap: () async => await shareVideo(context),
child: Icon(
Icons.share,
color: Colors.white,
),
),
),
Container(
padding: EdgeInsets.all(5),
width: 100,
height: 40,
decoration: BoxDecoration(
color: tesoGold,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
),
child: InkWell(
onTap: () => postVideo(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Post",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
Icon(
Icons.send,
color: tesoBlue,
),
],
),
),
),
],
),
),
);
} else {
return Align(
alignment: Alignment.bottomRight,
child: Container(
padding: EdgeInsets.all(5),
width: 100,
height: 40,
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 20,
),
decoration: BoxDecoration(
color: tesoGold,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
topLeft: Radius.circular(30),
),
),
child: InkWell(
onTap: () => postVideo(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Post",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
Icon(
Icons.send,
color: tesoBlue,
),
],
),
),
),
);
}
}
}

92
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/color_palette.dart

@ -1,92 +0,0 @@
import 'package:flutter/material.dart';
class ColorPalette extends StatefulWidget {
final Color activeColor;
final List<Color> colors;
final Function(Color) onColorPicked;
ColorPalette({
this.activeColor,
this.onColorPicked,
this.colors,
});
@override
_ColorPaletteState createState() => _ColorPaletteState();
}
class _ColorPaletteState extends State<ColorPalette> {
Color _activeColor;
@override
void initState() {
_activeColor = widget.activeColor ?? widget.colors[0];
super.initState();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16),
child: Wrap(
spacing: 16,
runSpacing: 16,
children: widget.colors
.map(
(color) => _ColorHolder(
color: color,
active: color == _activeColor,
onTap: (color) {
setState(() => _activeColor = color);
widget.onColorPicked(color);
},
),
)
.toList(),
),
);
}
}
class _ColorHolder extends StatelessWidget {
final Color color;
final Function(Color) onTap;
final bool active;
_ColorHolder({
this.color,
this.onTap,
this.active = false,
});
@override
Widget build(BuildContext context) {
return Container(
height: 40,
width: 40,
decoration: BoxDecoration(
border: active
? Border.fromBorderSide(
BorderSide(color: Theme.of(context).colorScheme.onSurface))
: null,
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: GestureDetector(
onTap: () => onTap(color),
child: Container(
height: 35,
width: 35,
decoration: BoxDecoration(
border: Border.fromBorderSide(
BorderSide(color: Theme.of(context).colorScheme.onSurface)),
borderRadius: BorderRadius.circular(50),
color: color,
),
),
),
),
);
}
}

30
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/option_button.dart

@ -1,30 +0,0 @@
import 'package:flutter/material.dart';
class OptionButton extends StatelessWidget {
final bool isActive;
final Function() onPressed;
final Widget child;
final Size size;
OptionButton({
this.onPressed,
this.child,
this.isActive = false,
this.size,
});
@override
Widget build(BuildContext context) {
return RawMaterialButton(
constraints: BoxConstraints.tight(size ?? Size(45, 45)),
highlightColor: Theme.of(context).colorScheme.background,
splashColor: Theme.of(context).colorScheme.background,
fillColor: isActive ? Theme.of(context).colorScheme.background : null,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: Theme.of(context).colorScheme.surface),
),
child: child,
onPressed: onPressed,
);
}
}

87
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/toolbar.dart

@ -1,87 +0,0 @@
import 'package:flutter/material.dart';
import 'option_button.dart';
import 'toolbar_action.dart';
class Toolbar extends StatefulWidget {
final EditorToolbarAction initialTool;
final Function(EditorToolbarAction) onToolSelect;
Toolbar({
this.initialTool = EditorToolbarAction.editor,
this.onToolSelect,
});
@override
_ToolbarState createState() => _ToolbarState();
}
class _ToolbarState extends State<Toolbar> {
EditorToolbarAction _selectedAction;
@override
void initState() {
_selectedAction = widget.initialTool;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// OptionButton(
// isActive: _selectedAction == EditorToolbarAction.editor,
// child: Icon(Icons.keyboard),
// onPressed: () {
// setState(() => _selectedAction = EditorToolbarAction.editor);
// widget.onToolSelect(EditorToolbarAction.editor);
// },
// ),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontFamilyTool,
child: Icon(Icons.title),
onPressed: () {
setState(
() => _selectedAction = EditorToolbarAction.fontFamilyTool);
widget.onToolSelect(EditorToolbarAction.fontFamilyTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontOptionTool,
child: Icon(Icons.strikethrough_s),
onPressed: () {
setState(
() => _selectedAction = EditorToolbarAction.fontOptionTool);
widget.onToolSelect(EditorToolbarAction.fontOptionTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontSizeTool,
child: Icon(Icons.format_size),
onPressed: () {
setState(() => _selectedAction = EditorToolbarAction.fontSizeTool);
widget.onToolSelect(EditorToolbarAction.fontSizeTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.fontColorTool,
child: Icon(Icons.format_color_text),
onPressed: () {
setState(() => _selectedAction = EditorToolbarAction.fontColorTool);
widget.onToolSelect(EditorToolbarAction.fontColorTool);
},
),
OptionButton(
isActive: _selectedAction == EditorToolbarAction.backgroundColorTool,
child: Icon(Icons.format_color_fill),
onPressed: () {
setState(() =>
_selectedAction = EditorToolbarAction.backgroundColorTool);
widget.onToolSelect(EditorToolbarAction.backgroundColorTool);
},
),
],
);
}
}

8
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/toolbar_action.dart

@ -1,8 +0,0 @@
enum EditorToolbarAction {
editor,
fontFamilyTool,
fontOptionTool,
fontSizeTool,
fontColorTool,
backgroundColorTool,
}

24
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/background_color_tool.dart

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
import '../color_palette.dart';
class BackgroundColorTool extends StatelessWidget {
final List<Color> colors;
final Color activeColor;
final Function(Color) onColorPicked;
BackgroundColorTool({
this.colors,
this.onColorPicked,
this.activeColor,
});
@override
Widget build(BuildContext context) {
return ColorPalette(
activeColor: activeColor,
onColorPicked: onColorPicked,
colors: colors,
);
}
}

24
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_color_tool.dart

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
import '../color_palette.dart';
class FontColorTool extends StatelessWidget {
final List<Color> colors;
final Color activeColor;
final Function(Color) onColorPicked;
FontColorTool({
this.colors,
this.onColorPicked,
this.activeColor,
});
@override
Widget build(BuildContext context) {
return ColorPalette(
activeColor: activeColor,
onColorPicked: onColorPicked,
colors: colors,
);
}
}

66
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_family_tool.dart

@ -1,66 +0,0 @@
import 'package:flutter/material.dart';
import '../option_button.dart';
class FontFamilyTool extends StatefulWidget {
final List<String> fonts;
final Function(String) onSelectFont;
final String selectedFont;
FontFamilyTool({
this.fonts,
this.onSelectFont,
this.selectedFont,
});
@override
_FontFamilyToolState createState() => _FontFamilyToolState();
}
class _FontFamilyToolState extends State<FontFamilyTool> {
String _selectedFont;
@override
void initState() {
_selectedFont = widget.selectedFont ?? widget.fonts[0];
super.initState();
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 12,
runSpacing: 12,
children: widget.fonts
.map<_FontFamily>(
(font) => _FontFamily(
font,
isSelected: _selectedFont == font,
onSelect: (selectedFont) {
setState(() => _selectedFont = selectedFont);
widget.onSelectFont(selectedFont);
},
),
)
.toList(),
);
}
}
class _FontFamily extends StatelessWidget {
final String font;
final bool isSelected;
final Function(String) onSelect;
_FontFamily(this.font, {this.onSelect, this.isSelected = false});
@override
Widget build(BuildContext context) {
return OptionButton(
isActive: isSelected,
size: Size(90, 45),
onPressed: () => onSelect(font),
child: Center(child: Text(font, style: TextStyle(fontFamily: font))),
);
}
}

123
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/font_size_tool.dart

@ -1,123 +0,0 @@
import 'package:flutter/material.dart';
class FontSizeTool extends StatelessWidget {
final double fontSize;
final double letterSpacing;
final double letterHeight;
final Function(
double fontSize,
double letterSpacing,
double letterHeight,
) onFontSizeEdited;
FontSizeTool({
this.onFontSizeEdited,
this.fontSize = 0,
this.letterSpacing = 0,
this.letterHeight = 0,
});
@override
Widget build(BuildContext context) {
double _fontSize = fontSize;
double _letterSpacing = letterSpacing;
double _letterHeight = letterHeight;
return Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
_ResizeSlider(
value: _fontSize,
max: 45,
icon: Icons.format_size,
onChange: (value) {
_fontSize = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
_ResizeSlider(
value: _letterHeight,
icon: Icons.format_line_spacing,
max: 10,
onChange: (value) {
_letterHeight = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
_ResizeSlider(
value: _letterSpacing,
icon: Icons.settings_ethernet,
max: 10,
onChange: (value) {
_letterSpacing = value;
onFontSizeEdited(_fontSize, _letterSpacing, _letterHeight);
},
),
],
),
);
}
}
class _ResizeSlider extends StatefulWidget {
final double value;
final double min;
final double max;
final IconData icon;
final Function(double) onChange;
_ResizeSlider({
this.value,
this.icon,
this.onChange,
this.min = 0,
this.max = 100,
});
@override
_ResizeSliderState createState() => _ResizeSliderState();
}
class _ResizeSliderState extends State<_ResizeSlider> {
double _value;
@override
void initState() {
_value = widget.value;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Icon(widget.icon),
Expanded(
child: SliderTheme(
data: SliderThemeData(
activeTrackColor: Theme.of(context).colorScheme.background,
inactiveTrackColor: Theme.of(context).colorScheme.background,
thumbColor: Theme.of(context).colorScheme.background,
overlayColor:
Theme.of(context).colorScheme.background.withOpacity(0.2),
trackHeight: 2,
),
child: Slider(
value: _value,
onChanged: (value) {
setState(() => _value = value);
widget.onChange(value);
},
min: widget.min,
max: widget.max,
),
),
),
Text(_value.toStringAsFixed(1)),
],
);
}
}

237
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/src/tools/text_format_tool.dart

@ -1,237 +0,0 @@
import 'package:flutter/material.dart';
import '../option_button.dart';
class TextFormatTool extends StatelessWidget {
final Function(
bool bold,
bool italic,
) onTextFormatEdited;
final Function(bool caps) onCpasLockTaggle;
final Function(TextAlign textAlign) onTextAlignEdited;
final TextAlign textAlign;
final bool bold;
final bool italic;
final bool caps;
TextFormatTool({
this.onTextFormatEdited,
this.onTextAlignEdited,
this.onCpasLockTaggle,
this.textAlign = TextAlign.left,
this.bold = false,
this.italic = false,
this.caps = false,
});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 36),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_TextFormatEditor(
bold: bold,
italic: italic,
caps: caps,
onFormatEdited: onTextFormatEdited,
onCpasLockTaggle: onCpasLockTaggle,
),
SizedBox(height: 36),
_TextAlignEditor(
textAlign: textAlign,
onTextAlignEdited: onTextAlignEdited,
),
],
),
);
}
}
class _TextAlignEditor extends StatefulWidget {
final TextAlign textAlign;
final Function(TextAlign textAlign) onTextAlignEdited;
_TextAlignEditor({
this.onTextAlignEdited,
this.textAlign = TextAlign.left,
});
@override
_TextAlignEditorState createState() => _TextAlignEditorState();
}
class _TextAlignEditorState extends State<_TextAlignEditor> {
TextAlign _textAlign;
@override
void initState() {
_textAlign = widget.textAlign;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_TextAlignOption(
icon: Icons.format_align_left,
isActive: _textAlign == TextAlign.left,
onPressed: () {
setState(() => _textAlign = TextAlign.left);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_center,
isActive: _textAlign == TextAlign.center,
onPressed: () {
setState(() => _textAlign = TextAlign.center);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_right,
isActive: _textAlign == TextAlign.right,
onPressed: () {
setState(() => _textAlign = TextAlign.right);
widget.onTextAlignEdited(_textAlign);
},
),
_TextAlignOption(
icon: Icons.format_align_justify,
isActive: _textAlign == TextAlign.justify,
onPressed: () {
setState(() => _textAlign = TextAlign.justify);
widget.onTextAlignEdited(_textAlign);
},
),
],
);
}
}
class _TextAlignOption extends StatelessWidget {
final IconData icon;
final Function() onPressed;
final bool isActive;
_TextAlignOption({
this.icon,
this.onPressed,
this.isActive = false,
});
@override
Widget build(BuildContext context) {
return IconButton(
iconSize: 32,
icon: Icon(icon),
color: isActive
? Theme.of(context).iconTheme.color
: Theme.of(context).disabledColor,
onPressed: onPressed,
);
}
}
class _TextFormatEditor extends StatefulWidget {
final Function(bool bold, bool italic) onFormatEdited;
final Function(bool caps) onCpasLockTaggle;
final bool bold;
final bool italic;
final bool caps;
_TextFormatEditor({
this.onFormatEdited,
this.onCpasLockTaggle,
this.bold = false,
this.italic = false,
this.caps = false,
});
@override
_TextFormatEditorState createState() => _TextFormatEditorState();
}
class _TextFormatEditorState extends State<_TextFormatEditor> {
bool _bold;
bool _italic;
bool _caps;
@override
void initState() {
_bold = widget.bold;
_italic = widget.italic;
_caps = widget.caps;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_TextFormatOption(
title: 'BOLD',
icon: Icons.format_bold,
isActive: _bold,
onPressed: () {
setState(() => _bold = !_bold);
widget.onFormatEdited(_bold, _italic);
},
),
_TextFormatOption(
title: 'ITALIC',
icon: Icons.format_italic,
isActive: _italic,
onPressed: () {
setState(() => _italic = !_italic);
widget.onFormatEdited(_bold, _italic);
},
),
_TextFormatOption(
title: 'CAPS',
icon: Icons.keyboard_capslock,
isActive: _caps,
onPressed: () {
setState(() => _caps = !_caps);
widget.onCpasLockTaggle(_caps);
},
),
],
);
}
}
class _TextFormatOption extends StatelessWidget {
final String title;
final IconData icon;
final Function() onPressed;
final bool isActive;
_TextFormatOption({
this.title,
this.icon,
this.onPressed,
this.isActive = false,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
OptionButton(
isActive: isActive,
onPressed: onPressed,
child: Icon(icon),
),
SizedBox(height: 12),
Text(title),
],
);
}
}

226
lib/Pages/Sub_Pages/Campaign/Video/Editor/textstyler/text_style_editor.dart

@ -1,226 +0,0 @@
library text_style_editor;
export 'src/toolbar_action.dart';
import 'package:flutter/material.dart';
import 'src/toolbar_action.dart';
import 'src/tools/background_color_tool.dart';
import 'src/color_palette.dart';
import 'src/tools/font_family_tool.dart';
import 'src/tools/font_size_tool.dart';
import 'src/tools/text_format_tool.dart';
import 'src/toolbar.dart';
/// Text style editor
/// A flutter widget that edit text style and text alignment
///
/// You can pass your text style or alignment to the widget
/// and then get the edited text style
class TextStyleEditor extends StatefulWidget {
/// Editor's font families
final List<String> fonts;
/// The text style
final TextStyle textStyle;
/// The text alignment
final TextAlign textAlign;
/// The inithial editor tool
final EditorToolbarAction initialTool;
/// Editor's palette colors
final List<Color> paletteColors;
/// [onTextStyleEdited] will be called after [textStyle] prop has changed
final Function(TextStyle) onTextStyleEdited;
/// [onTextAlignEdited] will be called after [textAlingment] prop has changed
final Function(TextAlign) onTextAlignEdited;
/// [onCpasLockTaggle] will be called after caps lock has changed
final Function(bool) onCpasLockTaggle;
/// [onToolbarActionChanged] will be called after editor's tool has changed
final Function(EditorToolbarAction) onToolbarActionChanged;
/// Create a [TextStyleEditor] widget
///
/// [fonts] list of font families that you want to use in editor.
/// [textStyle] initiate text style.
/// [textAlign] initiate text alignment.
///
/// [onTextStyleEdited] callback will be called every time [textStyle] has changed.
/// [onTextAlignEdited] callback will be called every time [textAlign] has changed.
/// [onCpasLockTaggle] callback will be called every time caps lock has changed to off or on.
/// [onToolbarActionChanged] callback will be called every time editor's tool has changed.
TextStyleEditor({
this.fonts,
this.textStyle,
this.textAlign,
this.paletteColors,
this.initialTool = EditorToolbarAction.editor,
this.onTextStyleEdited,
this.onTextAlignEdited,
this.onCpasLockTaggle,
this.onToolbarActionChanged,
});
@override
_TextStyleEditorState createState() => _TextStyleEditorState();
}
class _TextStyleEditorState extends State<TextStyleEditor> {
EditorToolbarAction _currentTool;
TextStyle _textStyle;
TextAlign _textAlign;
List<Color> _paletteColors;
@override
void initState() {
_currentTool = widget.initialTool;
_textStyle = widget.textStyle;
_textAlign = widget.textAlign;
// Set default palette's colors
_paletteColors = widget.paletteColors ??
[
Colors.black,
Colors.white,
Colors.red,
Colors.blue,
Colors.blueAccent,
Colors.brown,
Colors.green,
Colors.indigoAccent,
Colors.lime,
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).backgroundColor,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Toolbar(
initialTool: _currentTool,
onToolSelect: (action) {
setState(() => _currentTool = action);
if (widget.onToolbarActionChanged != null) {
widget.onToolbarActionChanged(action);
}
},
),
Divider(),
Container(
child: SingleChildScrollView(
child: () {
// Choice tools
switch (_currentTool) {
case EditorToolbarAction.fontFamilyTool:
return FontFamilyTool(
fonts: widget.fonts,
selectedFont: _textStyle.fontFamily,
onSelectFont: (fontFamily) {
setState(() => _textStyle =
_textStyle.copyWith(fontFamily: fontFamily));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.fontOptionTool:
return TextFormatTool(
bold: _textStyle.fontWeight == FontWeight.bold,
italic: _textStyle.fontStyle == FontStyle.italic,
textAlign: _textAlign,
onTextFormatEdited: (bold, italic) {
setState(() => _textStyle = _textStyle.copyWith(
fontWeight:
bold ? FontWeight.bold : FontWeight.normal,
fontStyle:
italic ? FontStyle.italic : FontStyle.normal,
));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
onTextAlignEdited: (align) {
setState(() => _textAlign = align);
if (widget.onTextAlignEdited != null) {
widget.onTextAlignEdited(align);
}
},
onCpasLockTaggle: (caps) {
if (widget.onCpasLockTaggle != null) {
widget.onCpasLockTaggle(caps);
}
},
);
case EditorToolbarAction.fontSizeTool:
return FontSizeTool(
fontSize: _textStyle.fontSize ?? 0,
letterHeight: _textStyle.height ?? 1.2,
letterSpacing: _textStyle.letterSpacing ?? 1,
onFontSizeEdited: (
fontSize,
letterSpacing,
letterHeight,
) {
setState(() => _textStyle = _textStyle.copyWith(
fontSize: fontSize,
height: letterHeight,
letterSpacing: letterSpacing,
));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.fontColorTool:
return BackgroundColorTool(
activeColor: _textStyle.color,
colors: _paletteColors,
onColorPicked: (color) {
setState(() =>
_textStyle = _textStyle.copyWith(color: color));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.backgroundColorTool:
return ColorPalette(
activeColor: _textStyle.backgroundColor,
colors: _paletteColors,
onColorPicked: (color) {
setState(() => _textStyle =
_textStyle.copyWith(backgroundColor: color));
if (widget.onTextStyleEdited != null) {
widget.onTextStyleEdited(_textStyle);
}
},
);
case EditorToolbarAction.editor:
return Container();
default:
return Container();
}
}(),
),
),
],
),
);
}
}

500
lib/Pages/Sub_Pages/Campaign/Video/RecordVideo.dart

@ -1,500 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:teso/util/consts.dart';
import 'package:page_transition/page_transition.dart';
import 'dart:async';
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:video_thumbnail/video_thumbnail.dart' as thumb;
import 'Editor/VideoReview.dart';
// ignore: must_be_immutable
class RecordVideo extends StatefulWidget {
final String campaignID;
List<CameraDescription> connectedCameras;
RecordVideo({Key key, this.connectedCameras, @required this.campaignID})
: super(key: key);
@override
_RecordVideoState createState() => _RecordVideoState();
}
class _RecordVideoState extends State<RecordVideo>
with TickerProviderStateMixin {
CameraController _controller;
int selectedCamera = 0;
bool flash = false;
bool frontFlash = false;
bool recording = false;
AnimationController _recordingAnimationController;
XFile video;
String filePath;
int recordEnd = 60;
CountDownController _controllerCountDown = CountDownController();
final interval = const Duration(seconds: 1);
final picker = ImagePicker();
bool gallery = false;
final int timerMaxSeconds = 60;
int currentSeconds = 0;
flipCamera() {
selectedCamera++;
if (selectedCamera < widget.connectedCameras.length) {
onNewCameraSelected(widget.connectedCameras.elementAt(selectedCamera));
} else {
selectedCamera = 0;
onNewCameraSelected(widget.connectedCameras.elementAt(selectedCamera));
}
}
flashCamera() {
try {
if (!flash &&
_controller.description.lensDirection == CameraLensDirection.back) {
_controller.setFlashMode(FlashMode.torch);
setState(() {
flash = true;
frontFlash = false;
});
} else if (!flash &&
_controller.description.lensDirection == CameraLensDirection.front) {
setState(() {
flash = true;
frontFlash = true;
});
} else if (flash &&
_controller.description.lensDirection == CameraLensDirection.back) {
_controller.setFlashMode(FlashMode.off);
setState(() {
flash = false;
});
} else {
setState(() {
flash = false;
frontFlash = false;
});
}
} catch (e) {}
}
haltRecord() async {
XFile recorded = await stopVideoRecording();
if (recorded != null)
Navigator.of(context).pushReplacement(
PageRouteBuilder(
opaque: false,
pageBuilder: (_, __, ___) => VideoReview(
video: recorded.path,
campaignID: widget.campaignID,
recorded: true,
),
),
);
}
Future<Uint8List> generateThumbnail(video) async {
try {
Uint8List thumbnail;
thumbnail = await thumb.VideoThumbnail.thumbnailData(
video: video,
imageFormat: thumb.ImageFormat.JPEG,
maxWidth: 0,
maxHeight: 0,
timeMs: 1,
quality: 100,
);
return thumbnail;
} catch (e) {
print("Error :::: " + e);
return null;
}
}
@override
void initState() {
if (widget.connectedCameras == null ||
widget.connectedCameras.length == 0) {
availableCameras().then((value) {
widget.connectedCameras = value;
onNewCameraSelected(widget.connectedCameras.first);
});
} else {
onNewCameraSelected(widget.connectedCameras.first);
}
_recordingAnimationController =
new AnimationController(vsync: this, duration: Duration(seconds: 1));
_recordingAnimationController.repeat(reverse: true);
super.initState();
}
sayCheese() async {
try {
if (flash && !frontFlash)
await _controller.setFlashMode(FlashMode.always);
await _controller.startVideoRecording();
} catch (e) {
print(e);
}
}
Future<XFile> stopVideoRecording() async {
if (!_controller.value.isRecordingVideo) {
return null;
}
try {
return _controller.stopVideoRecording();
} on CameraException catch (e) {
print(e);
return null;
}
}
void onNewCameraSelected(CameraDescription cameraDescription) async {
if (_controller != null) {
await _controller.dispose();
}
_controller = CameraController(
cameraDescription,
ResolutionPreset.high,
enableAudio: true,
imageFormatGroup: ImageFormatGroup.jpeg,
);
// If the controller is updated then update the UI.
_controller.addListener(() {
if (mounted) setState(() {});
if (_controller.value.hasError) {
print('Camera error ${_controller.value.errorDescription}');
}
});
try {
await _controller.initialize();
_controller.lockCaptureOrientation(DeviceOrientation.portraitUp);
_controller.setFocusMode(FocusMode.auto);
} on CameraException catch (e) {
print(e);
}
if (mounted) {
setState(() {});
}
}
void onHocusFocus(TapDownDetails details, BoxConstraints constraints) {
final offset = Offset(
details.localPosition.dx / constraints.maxWidth,
details.localPosition.dy / constraints.maxHeight,
);
_controller.setExposurePoint(offset);
_controller.setFocusPoint(offset);
}
@override
void dispose() {
_controller?.dispose();
_recordingAnimationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_controller == null || !_controller.value.isInitialized) {
return Container(
color: Colors.black,
);
} else {
return Scaffold(
body: !gallery
? Stack(
children: [
cameraWidget(context),
flashWidget(context),
cameraFlip(context),
cameraFlash(context),
recordingAnimation(context),
recordingCircle(context),
recorderWidget(context),
galleryPicker(context),
],
)
: Container(),
);
}
}
imgFromGallery() async {
try {
_controller?.dispose();
setState(() {
gallery = true;
});
final pickedFile = await picker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(minutes: 1),
);
if (pickedFile != null) {
return pickedFile.path;
} else {
onNewCameraSelected(widget.connectedCameras.first);
print('No image selected.');
}
} catch (e) {
print(e);
}
setState(() {
gallery = false;
});
return;
}
Widget recordingCircle(context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: CircularCountDownTimer(
duration: recordEnd,
initialDuration: 0,
controller: _controllerCountDown,
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 2,
ringColor: Colors.grey[300],
fillColor: Colors.red,
backgroundColor: Colors.transparent,
autoStart: false,
strokeWidth: 5.5,
isTimerTextShown: false,
strokeCap: StrokeCap.round,
//onStart: startTimeout,
onComplete: haltRecord,
),
),
);
}
Widget recorderWidget(context) {
return Align(
alignment: Alignment.bottomCenter,
child: InkWell(
onTap: recording
? haltRecord
: () async {
await _controller.startVideoRecording();
setState(() {
_controllerCountDown.start();
recording = !recording;
});
},
child: Container(
margin: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: Icon(
recording ? Icons.stop : Icons.video_camera_back,
color: Colors.white,
size: 25,
),
),
),
);
}
Widget galleryPicker(context) {
return Align(
alignment: Alignment.bottomLeft,
child: recording
? Container()
: InkWell(
onTap: () async {
String result = await imgFromGallery();
if (result != null) {
// _controller.dispose();
Navigator.pushReplacement(
context,
PageTransition(
type: PageTransitionType.leftToRight,
child: VideoReview(
video: result,
recorded: false,
campaignID: widget.campaignID,
),
));
}
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05,
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 70,
width: 70,
child: Icon(
Icons.photo,
color: Colors.white,
size: 27,
),
),
),
);
}
Widget recordingAnimation(context) {
if (!recording)
return Align(
alignment: Alignment.topLeft,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.08,
vertical: MediaQuery.of(context).size.width * 0.11,
),
height: 35,
width: 35,
decoration: BoxDecoration(
//color: ColorFilterEngineLayer (0, 0, 0, 0.4),
shape: BoxShape.circle),
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
));
else
return Align(
alignment: Alignment.topLeft,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: 5,
vertical: MediaQuery.of(context).size.width * 0.11,
),
padding: EdgeInsets.all(2.5),
height: 20,
width: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.red,
width: 2,
)),
child: FadeTransition(
opacity: _recordingAnimationController,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
),
],
),
),
);
}
Widget cameraFlash(context) {
return !recording
? Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.07,
vertical: MediaQuery.of(context).size.width * 0.25,
),
child: InkWell(
onTap: flashCamera,
child: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: flash ? tesoGold : Colors.white,
size: 30,
),
),
),
)
: Container();
}
Widget cameraFlip(context) {
return !recording
? Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.06,
vertical: MediaQuery.of(context).size.width * 0.11,
),
child: InkWell(
onTap: flipCamera,
child: Icon(
Icons.cameraswitch_outlined,
color: Colors.white,
size: 40,
),
),
),
)
: Container();
}
Widget flashWidget(context) {
return Visibility(
visible: frontFlash,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.4),
),
),
);
}
Widget cameraWidget(context) {
var camera = _controller.value;
final size = MediaQuery.of(context).size;
var scale = size.aspectRatio * camera.aspectRatio;
if (scale < 1) scale = 1 / scale;
return Transform.scale(
scale: scale,
child: Center(
child: CameraPreview(
_controller,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (details) => onHocusFocus(details, constraints),
);
}),
),
),
);
}
}

45
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/file_formats.dart

@ -1,45 +0,0 @@
/// The video file formats available for
/// generating the output trimmed video.
///
/// The available formats are `mp4`, `mkv`,
/// `mov`, `flv`, `avi`, `wmv`& `gif`.
///
/// If you define a custom `FFmpeg` command
/// then this will be ignored.
///
class FileFormat {
const FileFormat._(this.index);
final int index;
static const FileFormat mp4 = FileFormat._(0);
static const FileFormat mkv = FileFormat._(1);
static const FileFormat mov = FileFormat._(2);
static const FileFormat flv = FileFormat._(3);
static const FileFormat avi = FileFormat._(4);
static const FileFormat wmv = FileFormat._(5);
static const FileFormat gif = FileFormat._(6);
static const List<FileFormat> values = <FileFormat>[
mp4,
mkv,
mov,
flv,
avi,
wmv,
gif,
];
@override
String toString() {
return const <int, String>{
0: '.mp4',
1: '.mkv',
2: '.mov',
3: '.flv',
4: '.avi',
5: '.wmv',
6: '.gif',
}[index];
}
}

32
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/storage_dir.dart

@ -1,32 +0,0 @@
/// Supported storage locations.
///
/// * [temporaryDirectory]
///
/// * [applicationDocumentsDirectory]
///
/// * [externalStorageDirectory]
///
class StorageDir {
const StorageDir._(this.index);
final int index;
static const StorageDir temporaryDirectory = StorageDir._(0);
static const StorageDir applicationDocumentsDirectory = StorageDir._(1);
static const StorageDir externalStorageDirectory = StorageDir._(2);
static const List<StorageDir> values = <StorageDir>[
temporaryDirectory,
applicationDocumentsDirectory,
externalStorageDirectory,
];
@override
String toString() {
return const <int, String>{
0: 'temporaryDirectory',
1: 'applicationDocumentsDirectory',
2: 'externalStorageDirectory',
}[index];
}
}

81
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/thumbnail_viewer.dart

@ -1,81 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class ThumbnailViewer extends StatelessWidget {
final videoFile;
final videoDuration;
final thumbnailHeight;
final fit;
final int numberOfThumbnails;
final int quality;
/// For showing the thumbnails generated from the video,
/// like a frame by frame preview
ThumbnailViewer({
@required this.videoFile,
@required this.videoDuration,
@required this.thumbnailHeight,
@required this.numberOfThumbnails,
@required this.fit,
this.quality = 75,
}) : assert(videoFile != null),
assert(videoDuration != null),
assert(thumbnailHeight != null),
assert(numberOfThumbnails != null),
assert(quality != null);
Stream<List<Uint8List>> generateThumbnail() async* {
final String _videoPath = videoFile.path;
double _eachPart = videoDuration / numberOfThumbnails;
List<Uint8List> _byteList = [];
for (int i = 1; i <= numberOfThumbnails; i++) {
Uint8List _bytes;
_bytes = await VideoThumbnail.thumbnailData(
video: _videoPath,
imageFormat: ImageFormat.JPEG,
timeMs: (_eachPart * i).toInt(),
quality: quality,
);
_byteList.add(_bytes);
yield _byteList;
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: generateThumbnail(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Uint8List> _imageBytes = snapshot.data;
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Container(
height: thumbnailHeight,
width: thumbnailHeight,
child: Image(
image: MemoryImage(_imageBytes[index]),
fit: fit,
),
);
});
} else {
return Container(
color: Colors.grey[900],
height: thumbnailHeight,
width: double.maxFinite,
);
}
},
);
}
}

537
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor.dart

@ -1,537 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/thumbnail_viewer.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor_painter.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/trimmer.dart';
import 'package:video_player/video_player.dart';
VideoPlayerController videoPlayerController;
class TrimEditor extends StatefulWidget {
/// For defining the total trimmer area width
final double viewerWidth;
/// For defining the total trimmer area height
final double viewerHeight;
/// For defining the image fit type of each thumbnail image.
///
/// By default it is set to `BoxFit.fitHeight`.
final BoxFit fit;
/// For defining the maximum length of the output video.
final Duration maxVideoLength;
/// For specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
///
/// By default it is set to `5.0`.
final double circleSize;
/// For specifying a size to the holder at
/// the two ends of the video trimmer area, while it is being
/// `dragged`.
///
/// By default it is set to `8.0`.
final double circleSizeOnDrag;
/// For specifying a color to the circle.
///
/// By default it is set to `Colors.white`.
final Color circlePaintColor;
/// For specifying a color to the border of
/// the trim area.
///
/// By default it is set to `Colors.white`.
final Color borderPaintColor;
/// For specifying a color to the video
/// scrubber inside the trim area.
///
/// By default it is set to `Colors.white`.
final Color scrubberPaintColor;
/// For specifying the quality of each
/// generated image thumbnail, to be displayed in the trimmer
/// area.
final int thumbnailQuality;
/// For showing the start and the end point of the
/// video on top of the trimmer area.
///
/// By default it is set to `true`.
final bool showDuration;
/// For providing a `TextStyle` to the
/// duration text.
///
/// By default it is set to `TextStyle(color: Colors.white)`
final TextStyle durationTextStyle;
/// Callback to the video start position
///
/// Returns the selected video start position in `milliseconds`.
final Function(double startValue) onChangeStart;
/// Callback to the video end position.
///
/// Returns the selected video end position in `milliseconds`.
final Function(double endValue) onChangeEnd;
/// Callback to the video playback
/// state to know whether it is currently playing or paused.
///
/// Returns a `boolean` value. If `true`, video is currently
/// playing, otherwise paused.
final Function(bool isPlaying) onChangePlaybackState;
/// Widget for displaying the video trimmer.
///
/// This has frame wise preview of the video with a
/// slider for selecting the part of the video to be
/// trimmed.
///
/// The required parameters are [viewerWidth] & [viewerHeight]
///
/// * [viewerWidth] to define the total trimmer area width.
///
///
/// * [viewerHeight] to define the total trimmer area height.
///
///
/// The optional parameters are:
///
/// * [fit] for specifying the image fit type of each thumbnail image.
/// By default it is set to `BoxFit.fitHeight`.
///
///
/// * [maxVideoLength] for specifying the maximum length of the
/// output video.
///
///
/// * [circleSize] for specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `5.0`.
///
///
/// * [circleSizeOnDrag] for specifying a size to the holder at
/// the two ends of the video trimmer area, while it is being
/// `dragged`. By default it is set to `8.0`.
///
///
/// * [circlePaintColor] for specifying a color to the circle.
/// By default it is set to `Colors.white`.
///
///
/// * [borderPaintColor] for specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
///
///
/// * [scrubberPaintColor] for specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
///
///
/// * [thumbnailQuality] for specifying the quality of each
/// generated image thumbnail, to be displayed in the trimmer
/// area.
///
///
/// * [showDuration] for showing the start and the end point of the
/// video on top of the trimmer area. By default it is set to `true`.
///
///
/// * [durationTextStyle] is for providing a `TextStyle` to the
/// duration text. By default it is set to
/// `TextStyle(color: Colors.white)`
///
///
/// * [onChangeStart] is a callback to the video start position.
///
///
/// * [onChangeEnd] is a callback to the video end position.
///
///
/// * [onChangePlaybackState] is a callback to the video playback
/// state to know whether it is currently playing or paused.
///
TrimEditor({
@required this.viewerWidth,
@required this.viewerHeight,
this.fit = BoxFit.fitHeight,
this.maxVideoLength = const Duration(milliseconds: 0),
this.circleSize = 5.0,
this.circleSizeOnDrag = 8.0,
this.circlePaintColor = Colors.white,
this.borderPaintColor = Colors.white,
this.scrubberPaintColor = Colors.white,
this.thumbnailQuality = 75,
this.showDuration = true,
this.durationTextStyle = const TextStyle(
color: Colors.white,
),
this.onChangeStart,
this.onChangeEnd,
this.onChangePlaybackState,
}) : assert(viewerWidth != null),
assert(viewerHeight != null),
assert(fit != null),
assert(maxVideoLength != null),
assert(circleSize != null),
assert(circleSizeOnDrag != null),
assert(circlePaintColor != null),
assert(borderPaintColor != null),
assert(scrubberPaintColor != null),
assert(thumbnailQuality != null),
assert(showDuration != null),
assert(durationTextStyle != null);
@override
_TrimEditorState createState() => _TrimEditorState();
}
class _TrimEditorState extends State<TrimEditor> with TickerProviderStateMixin {
File _videoFile;
double _videoStartPos = 0.0;
double _videoEndPos = 0.0;
bool _canUpdateStart = true;
bool _isLeftDrag = true;
Offset _startPos = Offset(0, 0);
Offset _endPos = Offset(0, 0);
double _startFraction = 0.0;
double _endFraction = 1.0;
int _videoDuration = 0;
int _currentPosition = 0;
double _thumbnailViewerW = 0.0;
double _thumbnailViewerH = 0.0;
int _numberOfThumbnails = 0;
double _circleSize;
double fraction;
double maxLengthPixels;
ThumbnailViewer thumbnailWidget;
Animation<double> _scrubberAnimation;
AnimationController _animationController;
Tween<double> _linearTween;
Future<void> _initializeVideoController() async {
if (_videoFile != null) {
videoPlayerController.addListener(() {
final bool isPlaying = videoPlayerController.value.isPlaying;
if (isPlaying) {
widget.onChangePlaybackState(true);
setState(() {
_currentPosition =
videoPlayerController.value.position.inMilliseconds;
if (_currentPosition > _videoEndPos.toInt()) {
widget.onChangePlaybackState(false);
videoPlayerController.pause();
_animationController.stop();
} else {
if (!_animationController.isAnimating) {
widget.onChangePlaybackState(true);
_animationController.forward();
}
}
});
} else {
if (videoPlayerController.value.isInitialized) {
if (_animationController != null) {
if ((_scrubberAnimation.value).toInt() == (_endPos.dx).toInt()) {
_animationController.reset();
}
_animationController.stop();
widget.onChangePlaybackState(false);
}
}
}
});
videoPlayerController.setVolume(1.0);
_videoDuration = videoPlayerController.value.duration.inMilliseconds;
print(_videoFile.path);
_videoEndPos = fraction != null
? _videoDuration.toDouble() * fraction
: _videoDuration.toDouble();
widget.onChangeEnd(_videoEndPos);
final ThumbnailViewer _thumbnailWidget = ThumbnailViewer(
videoFile: _videoFile,
videoDuration: _videoDuration,
fit: widget.fit,
thumbnailHeight: _thumbnailViewerH,
numberOfThumbnails: _numberOfThumbnails,
quality: widget.thumbnailQuality,
);
thumbnailWidget = _thumbnailWidget;
}
}
void _setVideoStartPosition(DragUpdateDetails details) async {
if (!(_startPos.dx + details.delta.dx < 0) &&
!(_startPos.dx + details.delta.dx > _thumbnailViewerW) &&
!(_startPos.dx + details.delta.dx > _endPos.dx)) {
if (maxLengthPixels != null) {
if (!(_endPos.dx - _startPos.dx - details.delta.dx > maxLengthPixels)) {
setState(() {
if (!(_startPos.dx + details.delta.dx < 0))
_startPos += details.delta;
_startFraction = (_startPos.dx / _thumbnailViewerW);
_videoStartPos = _videoDuration * _startFraction;
widget.onChangeStart(_videoStartPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoStartPos.toInt()));
_linearTween.begin = _startPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
} else {
setState(() {
if (!(_startPos.dx + details.delta.dx < 0))
_startPos += details.delta;
_startFraction = (_startPos.dx / _thumbnailViewerW);
_videoStartPos = _videoDuration * _startFraction;
widget.onChangeStart(_videoStartPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoStartPos.toInt()));
_linearTween.begin = _startPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
}
}
void _setVideoEndPosition(DragUpdateDetails details) async {
if (!(_endPos.dx + details.delta.dx > _thumbnailViewerW) &&
!(_endPos.dx + details.delta.dx < 0) &&
!(_endPos.dx + details.delta.dx < _startPos.dx)) {
if (maxLengthPixels != null) {
if (!(_endPos.dx - _startPos.dx + details.delta.dx > maxLengthPixels)) {
setState(() {
_endPos += details.delta;
_endFraction = _endPos.dx / _thumbnailViewerW;
_videoEndPos = _videoDuration * _endFraction;
widget.onChangeEnd(_videoEndPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoEndPos.toInt()));
_linearTween.end = _endPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
} else {
setState(() {
_endPos += details.delta;
_endFraction = _endPos.dx / _thumbnailViewerW;
_videoEndPos = _videoDuration * _endFraction;
widget.onChangeEnd(_videoEndPos);
});
await videoPlayerController.pause();
await videoPlayerController
.seekTo(Duration(milliseconds: _videoEndPos.toInt()));
_linearTween.end = _endPos.dx;
_animationController.duration =
Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt());
_animationController.reset();
}
}
}
@override
void initState() {
super.initState();
_circleSize = widget.circleSize;
_videoFile = Trimmer.currentVideoFile;
_thumbnailViewerH = widget.viewerHeight;
_numberOfThumbnails = widget.viewerWidth ~/ _thumbnailViewerH;
_thumbnailViewerW = _numberOfThumbnails * _thumbnailViewerH;
Duration totalDuration = videoPlayerController.value.duration;
if (widget.maxVideoLength > Duration(milliseconds: 0) &&
widget.maxVideoLength < totalDuration) {
if (widget.maxVideoLength < totalDuration) {
fraction =
widget.maxVideoLength.inMilliseconds / totalDuration.inMilliseconds;
maxLengthPixels = _thumbnailViewerW * fraction;
}
}
_initializeVideoController();
_endPos = Offset(
maxLengthPixels != null ? maxLengthPixels : _thumbnailViewerW,
_thumbnailViewerH,
);
// Defining the tween points
_linearTween = Tween(begin: _startPos.dx, end: _endPos.dx);
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: (_videoEndPos - _videoStartPos).toInt()),
);
_scrubberAnimation = _linearTween.animate(_animationController)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.stop();
}
});
}
@override
void dispose() {
videoPlayerController.pause();
widget.onChangePlaybackState(false);
if (_videoFile != null) {
videoPlayerController.setVolume(0.0);
videoPlayerController.pause();
videoPlayerController.dispose();
widget.onChangePlaybackState(false);
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onHorizontalDragStart: (DragStartDetails details) {
print("START");
print(details.localPosition);
print((_startPos.dx - details.localPosition.dx).abs());
print((_endPos.dx - details.localPosition.dx).abs());
if (_endPos.dx >= _startPos.dx) {
if ((_startPos.dx - details.localPosition.dx).abs() >
(_endPos.dx - details.localPosition.dx).abs()) {
setState(() {
_canUpdateStart = false;
});
} else {
setState(() {
_canUpdateStart = true;
});
}
} else {
if (_startPos.dx > details.localPosition.dx) {
_isLeftDrag = true;
} else {
_isLeftDrag = false;
}
}
},
onHorizontalDragEnd: (DragEndDetails details) {
setState(() {
_circleSize = widget.circleSize;
});
},
onHorizontalDragUpdate: (DragUpdateDetails details) {
_circleSize = widget.circleSizeOnDrag;
if (_endPos.dx >= _startPos.dx) {
_isLeftDrag = false;
if (_canUpdateStart && _startPos.dx + details.delta.dx > 0) {
_isLeftDrag = false; // To prevent from scrolling over
_setVideoStartPosition(details);
} else if (!_canUpdateStart &&
_endPos.dx + details.delta.dx < _thumbnailViewerW) {
_isLeftDrag = true; // To prevent from scrolling over
_setVideoEndPosition(details);
}
} else {
if (_isLeftDrag && _startPos.dx + details.delta.dx > 0) {
_setVideoStartPosition(details);
} else if (!_isLeftDrag &&
_endPos.dx + details.delta.dx < _thumbnailViewerW) {
_setVideoEndPosition(details);
}
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
widget.showDuration
? Container(
width: _thumbnailViewerW,
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
Duration(milliseconds: _videoStartPos.toInt())
.toString()
.split('.')[0],
style: widget.durationTextStyle,
),
Text(
Duration(milliseconds: _videoEndPos.toInt())
.toString()
.split('.')[0],
style: widget.durationTextStyle,
),
],
),
),
)
: Container(),
CustomPaint(
foregroundPainter: TrimEditorPainter(
startPos: _startPos,
endPos: _endPos,
scrubberAnimationDx: _scrubberAnimation.value,
circleSize: _circleSize,
circlePaintColor: widget.circlePaintColor,
borderPaintColor: widget.borderPaintColor,
scrubberPaintColor: widget.scrubberPaintColor,
),
child: Container(
color: Colors.grey[900],
height: _thumbnailViewerH,
width: _thumbnailViewerW,
child: thumbnailWidget == null ? Column() : thumbnailWidget,
),
),
],
),
);
}
}

150
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor_painter.dart

@ -1,150 +0,0 @@
import 'package:flutter/material.dart';
class TrimEditorPainter extends CustomPainter {
/// To define the start offset
final Offset startPos;
/// To define the end offset
final Offset endPos;
/// To define the horizontal length of the selected video area
final double scrubberAnimationDx;
/// For specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `0.5`.
final double circleSize;
/// For specifying the width of the border around
/// the trim area. By default it is set to `3`.
final double borderWidth;
/// For specifying the width of the video scrubber
final double scrubberWidth;
/// For specifying whether to show the scrubber
final bool showScrubber;
/// For specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
final Color borderPaintColor;
/// For specifying a color to the circle.
/// By default it is set to `Colors.white`
final Color circlePaintColor;
/// For specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
final Color scrubberPaintColor;
/// For drawing the trim editor slider
///
/// The required parameters are [startPos], [endPos]
/// & [scrubberAnimationDx]
///
/// * [startPos] to define the start offset
///
///
/// * [endPos] to define the end offset
///
///
/// * [scrubberAnimationDx] to define the horizontal length of the
/// selected video area
///
///
/// The optional parameters are:
///
/// * [circleSize] for specifying a size to the holder at the
/// two ends of the video trimmer area, while it is `idle`.
/// By default it is set to `0.5`.
///
///
/// * [borderWidth] for specifying the width of the border around
/// the trim area. By default it is set to `3`.
///
///
/// * [scrubberWidth] for specifying the width of the video scrubber
///
///
/// * [showScrubber] for specifying whether to show the scrubber
///
///
/// * [borderPaintColor] for specifying a color to the border of
/// the trim area. By default it is set to `Colors.white`.
///
///
/// * [circlePaintColor] for specifying a color to the circle.
/// By default it is set to `Colors.white`.
///
///
/// * [scrubberPaintColor] for specifying a color to the video
/// scrubber inside the trim area. By default it is set to
/// `Colors.white`.
///
TrimEditorPainter({
@required this.startPos,
@required this.endPos,
@required this.scrubberAnimationDx,
this.circleSize = 0.5,
this.borderWidth = 3,
this.scrubberWidth = 1,
this.showScrubber = true,
this.borderPaintColor = Colors.white,
this.circlePaintColor = Colors.white,
this.scrubberPaintColor = Colors.white,
}) : assert(startPos != null),
assert(endPos != null),
assert(scrubberAnimationDx != null),
assert(circleSize != null),
assert(borderWidth != null),
assert(scrubberWidth != null),
assert(showScrubber != null),
assert(borderPaintColor != null),
assert(circlePaintColor != null),
assert(scrubberPaintColor != null);
@override
void paint(Canvas canvas, Size size) {
var borderPaint = Paint()
..color = borderPaintColor
..strokeWidth = borderWidth
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
var circlePaint = Paint()
..color = circlePaintColor
..strokeWidth = 1
..style = PaintingStyle.fill
..strokeCap = StrokeCap.round;
var scrubberPaint = Paint()
..color = scrubberPaintColor
..strokeWidth = scrubberWidth
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
final rect = Rect.fromPoints(startPos, endPos);
if (showScrubber) {
if (scrubberAnimationDx.toInt() > startPos.dx.toInt()) {
canvas.drawLine(
Offset(scrubberAnimationDx, 0),
Offset(scrubberAnimationDx, 0) + Offset(0, endPos.dy),
scrubberPaint,
);
}
}
canvas.drawRect(rect, borderPaint);
canvas.drawCircle(
startPos + Offset(0, endPos.dy / 2), circleSize, circlePaint);
canvas.drawCircle(
endPos + Offset(0, -endPos.dy / 2), circleSize, circlePaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

300
lib/Pages/Sub_Pages/Campaign/Video/Trimmer/trimmer.dart

@ -1,300 +0,0 @@
import 'dart:io';
import 'package:path/path.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/file_formats.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/storage_dir.dart';
import 'package:teso/Pages/Sub_Pages/Campaign/Video/Trimmer/trim_editor.dart';
import 'package:video_player/video_player.dart';
/// Helps in loading video from file, saving trimmed video to a file
/// and gives video playback controls. Some of the helpful methods
/// are:
/// * [loadVideo()]
/// * [saveTrimmedVideo()]
/// * [videPlaybackControl()]
class Trimmer {
static File currentVideoFile;
final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
/// Loads a video using the path provided.
///
/// Returns the loaded video file.
Future<void> loadVideo({@required File videoFile}) async {
currentVideoFile = videoFile;
if (currentVideoFile != null) {
videoPlayerController = VideoPlayerController.file(currentVideoFile);
await videoPlayerController.initialize().then((_) {
TrimEditor(
viewerHeight: 50,
viewerWidth: 50.0 * 8,
// currentVideoFile: currentVideoFile,
);
});
// TrimEditor(
// viewerHeight: 50,
// viewerWidth: 50.0 * 8,
// // currentVideoFile: currentVideoFile,
// );
}
}
Future<String> _createFolderInAppDocDir(
String folderName,
StorageDir storageDir,
) async {
Directory _directory;
if (storageDir == null) {
_directory = await getApplicationDocumentsDirectory();
} else {
switch (storageDir.toString()) {
case 'temporaryDirectory':
_directory = await getTemporaryDirectory();
break;
case 'applicationDocumentsDirectory':
_directory = await getApplicationDocumentsDirectory();
break;
case 'externalStorageDirectory':
_directory = await getExternalStorageDirectory();
break;
}
}
// Directory + folder name
final Directory _directoryFolder =
Directory('${_directory.path}/$folderName/');
if (await _directoryFolder.exists()) {
// If folder already exists return path
print('Exists');
return _directoryFolder.path;
} else {
print('Creating');
// If folder does not exists create folder and then return its path
final Directory _directoryNewFolder =
await _directoryFolder.create(recursive: true);
return _directoryNewFolder.path;
}
}
/// Saves the trimmed video to file system.
///
/// Returns the output video path
///
/// The required parameters are [startValue] & [endValue].
///
/// The optional parameters are [videoFolderName], [videoFileName],
/// [outputFormat], [fpsGIF], [scaleGIF], [applyVideoEncoding].
///
/// The `@required` parameter [startValue] is for providing a starting point
/// to the trimmed video. To be specified in `milliseconds`.
///
/// The `@required` parameter [endValue] is for providing an ending point
/// to the trimmed video. To be specified in `milliseconds`.
///
/// The parameter [videoFolderName] is used to
/// pass a folder name which will be used for creating a new
/// folder in the selected directory. The default value for
/// it is `Trimmer`.
///
/// The parameter [videoFileName] is used for giving
/// a new name to the trimmed video file. By default the
/// trimmed video is named as `<original_file_name>_trimmed.mp4`.
///
/// The parameter [outputFormat] is used for providing a
/// file format to the trimmed video. This only accepts value
/// of [FileFormat] type. By default it is set to `FileFormat.mp4`,
/// which is for `mp4` files.
///
/// The parameter [storageDir] can be used for providing a storage
/// location option. It accepts only [StorageDir] values. By default
/// it is set to [applicationDocumentsDirectory]. Some of the
/// storage types are:
///
/// * [temporaryDirectory] (Only accessible from inside the app, can be
/// cleared at anytime)
///
/// * [applicationDocumentsDirectory] (Only accessible from inside the app)
///
/// * [externalStorageDirectory] (Supports only `Android`, accessible externally)
///
/// The parameters [fpsGIF] & [scaleGIF] are used only if the
/// selected output format is `FileFormat.gif`.
///
/// * [fpsGIF] for providing a FPS value (by default it is set
/// to `10`)
///
///
/// * [scaleGIF] for proving a width to output GIF, the height
/// is selected by maintaining the aspect ratio automatically (by
/// default it is set to `480`)
///
///
/// * [applyVideoEncoding] for specifying whether to apply video
/// encoding (by default it is set to `false`).
///
///
/// ADVANCED OPTION:
///
/// If you want to give custom `FFmpeg` command, then define
/// [ffmpegCommand] & [customVideoFormat] strings. The `input path`,
/// `output path`, `start` and `end` position is already define.
///
/// NOTE: The advanced option does not provide any safety check, so if wrong
/// video format is passed in [customVideoFormat], then the app may
/// crash.
///
Future<String> saveTrimmedVideo({
@required double startValue,
@required double endValue,
bool applyVideoEncoding = false,
FileFormat outputFormat,
String ffmpegCommand,
String customVideoFormat,
int fpsGIF,
int scaleGIF,
String videoFolderName,
String videoFileName,
StorageDir storageDir,
}) async {
final String _videoPath = currentVideoFile.path;
final String _videoName = basename(_videoPath).split('.')[0];
String _command;
// Formatting Date and Time
String dateTime = DateFormat.yMMMd()
.addPattern('-')
.add_Hms()
.format(DateTime.now())
.toString();
// String _resultString;
String _outputPath;
String _outputFormatString;
String formattedDateTime = dateTime.replaceAll(' ', '');
print("DateTime: $dateTime");
print("Formatted: $formattedDateTime");
if (videoFolderName == null) {
videoFolderName = "Trimmer";
}
if (videoFileName == null) {
videoFileName = "${_videoName}_trimmed:$formattedDateTime";
}
videoFileName = videoFileName.replaceAll(' ', '_');
String path = await _createFolderInAppDocDir(
videoFolderName,
storageDir,
).whenComplete(
() => print("Retrieved Trimmer folder"),
);
Duration startPoint = Duration(milliseconds: startValue.toInt());
Duration endPoint = Duration(milliseconds: endValue.toInt());
// Checking the start and end point strings
print("Start: ${startPoint.toString()} & End: ${endPoint.toString()}");
print(path);
if (outputFormat == null) {
if (Platform.isIOS) {
outputFormat = FileFormat.mp4;
} else {
outputFormat = FileFormat.mkv;
}
_outputFormatString = outputFormat.toString();
print('OUTPUT: $_outputFormatString');
} else {
_outputFormatString = outputFormat.toString();
}
String _trimLengthCommand =
' -ss $startPoint -i "$_videoPath" -t ${endPoint - startPoint} -avoid_negative_ts make_zero ';
if (ffmpegCommand == null) {
_command = '$_trimLengthCommand -c:a copy ';
if (!applyVideoEncoding) {
_command += '-c:v copy ';
}
if (outputFormat == FileFormat.gif) {
if (fpsGIF == null) {
fpsGIF = 10;
}
if (scaleGIF == null) {
scaleGIF = 480;
}
_command =
'$_trimLengthCommand -vf "fps=$fpsGIF,scale=$scaleGIF:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ';
}
} else {
_command = '$_trimLengthCommand $ffmpegCommand ';
_outputFormatString = customVideoFormat;
}
_outputPath = '$path$videoFileName$_outputFormatString';
_command += '"$_outputPath"';
await _flutterFFmpeg.execute(_command).whenComplete(() {
print('Got value');
debugPrint('Video successfuly saved');
// _resultString = 'Video successfuly saved';
}).catchError((error) {
print('Error');
// _resultString = 'Couldn\'t save the video';
debugPrint('Couldn\'t save the video');
});
return _outputPath;
}
/// For getting the video controller state, to know whether the
/// video is playing or paused currently.
///
/// The two required parameters are [startValue] & [endValue]
///
/// * [startValue] is the current starting point of the video.
/// * [endValue] is the current ending point of the video.
///
/// Returns a `Future<bool>`, if `true` then video is playing
/// otherwise paused.
Future<bool> videPlaybackControl({
@required double startValue,
@required double endValue,
}) async {
if (videoPlayerController.value.isPlaying) {
await videoPlayerController.pause();
return false;
} else {
if (videoPlayerController.value.position.inMilliseconds >=
endValue.toInt()) {
await videoPlayerController
.seekTo(Duration(milliseconds: startValue.toInt()));
await videoPlayerController.play();
return true;
} else {
await videoPlayerController.play();
return true;
}
}
}
File getVideoFile() {
return currentVideoFile;
}
}

2
lib/Pages/Sub_Pages/LandingPage/Login.dart

@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:crypto/crypto.dart';
import 'package:provider/provider.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

2
lib/Pages/Sub_Pages/LandingPage/createPassword.dart

@ -11,7 +11,7 @@ import 'dart:math' as math;
import 'package:teso/Pages/PageWidgets/Login/validation.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'dart:io';
import 'dart:ui';
class CreatePassword extends StatefulWidget {
final TesoUser newuser;

2
lib/Pages/Sub_Pages/Notifications/ChatScreen.dart

@ -11,7 +11,7 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:ui';
import 'package:intl/intl.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:provider/provider.dart';

92
lib/Pages/Sub_Pages/PersonalSub/Posts.dart

@ -1,92 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/Pages/PageWidgets/Posts/user_posted.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:teso/Pages/PageWidgets/Uploads/Pending.dart';
import 'package:teso/Pages/Sub_Pages/@Generic/Camera/Video/RecordVideo.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/Pages/PageWidgets/Personal/Empty.dart';
class Posts extends StatefulWidget {
@override
_PostsState createState() => _PostsState();
}
class _PostsState extends State<Posts> {
// ScrollController _controller;
List<FBPosts> trends = <FBPosts>[];
List<FBPosts> show = <FBPosts>[];
int count;
Uint8List thumbnail;
SharedPreferences prefs;
bool loading = false;
void postContent(context) async {
await Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
pageBuilder: (_, __, ___) => RecordVideo(),
),
);
}
@override
Widget build(BuildContext context) {
return Consumer<UserProvider>(
builder: (context, UserProvider value, child) {
if (value.posts == null || value.posts.isEmpty) {
return buildEmpty(context, postContent);
} else {
return StaggeredGridView.count(
crossAxisCount: 3,
children: List.generate(value.posts.length, (int index) {
// if (index == 0 && provider.isNotEmpty) {
return buildPosted(context, value.posts.elementAt(index), 0.325);
// }else{
// return buildPosted(
// context, value.posts.elementAt(index), 0.325);
// }
}),
staggeredTiles: List.generate(
value.posts.length,
(int index) {
return StaggeredTile.fit(1);
},
),
);
}
},
);
// : Center(
// child: CupertinoActivityIndicator(
// animating: true,
// radius: 15,
// ),
// );
}
Widget getTiles(BuildContext context, value) {
try {
List<Uploading> provider = value.getPending();
if (value.pending != null) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: ListView(
children: provider
.map<Widget>((item) => uploadTile(context, item))
.toList()),
);
} else {
return Container();
}
} catch (e) {
return Container();
}
}
}

196
lib/Pages/Sub_Pages/Posts/CreatePost.dart

@ -1,196 +0,0 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:http/http.dart' as http;
class CreatePost extends StatefulWidget {
final String video;
final Uint8List thumbnail;
final String aspectRatio;
const CreatePost({
Key key,
this.video,
this.thumbnail,
this.aspectRatio,
}) : super(key: key);
@override
_CreatePostState createState() => _CreatePostState();
}
class _CreatePostState extends State<CreatePost> {
String aspectRatio;
TextEditingController controller;
SharedPreferences prefs;
bool sending = false;
void postVideo(context) async {
setState(() {
sending = true;
});
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("tokensTeso");
Map<String, String> requestHeaders = {'Authorization': token};
String urlLocation = tesoStreaming + "api/mobile/upload/authurl";
var client =
await http.get(Uri.parse(urlLocation), headers: requestHeaders);
if (client.statusCode == 200) {
var details = jsonDecode(client.body);
String muxuploadsID = details["data"]["id"];
String muxuploadsURL = details["data"]["url"];
Provider.of<UserProvider>(context, listen: false).uploadPost(Uploading(
id: DateTime.now().toString() +
widget.video.replaceAll("file://", ""),
aspect: widget.aspectRatio,
path: widget.video.replaceAll("file://", ""),
thumbnail:
widget.thumbnail != null ? base64Encode(widget.thumbnail) : null,
title: controller.text.isNotEmpty ? controller.text : "",
pending: 0,
muxuploadID: muxuploadsID,
muxuploadURL: muxuploadsURL,
));
Navigator.pop(context);
}
} catch (e) {
print(e);
}
setState(() {
sending = false;
});
}
@override
void initState() {
super.initState();
controller = new TextEditingController();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
child: AppBar(
automaticallyImplyLeading: true,
title: Text("Post"),
centerTitle: true,
),
preferredSize: Size.fromHeight(70.0),
),
body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.025),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.25,
height: MediaQuery.of(context).size.width * 0.35,
color: Colors.black,
child: widget.thumbnail != null
? Image.memory(widget.thumbnail)
: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
Container(
width: (MediaQuery.of(context).size.width) -
(MediaQuery.of(context).size.width * 0.35),
height: MediaQuery.of(context).size.width * 0.35,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide.none,
),
filled: true,
isDense: true,
labelText: "Say Something..",
labelStyle: TextStyle(
color: Colors.black54,
),
fillColor: Colors.white70,
),
controller: controller,
maxLines: null,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
),
),
],
),
),
SizedBox(
height: 20,
),
Divider(),
Container(
margin: EdgeInsets.only(
top: 10,
),
child: Text(
"Teso businesses and other Teso users can see your post in their feeds and on your profile.",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey,
),
),
),
],
),
),
),
floatingActionButton: !sending
? Container(
margin: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: tesoBlue,
),
child: InkWell(
onTap: () => postVideo(context),
child: Center(
child: Text(
"NEXT",
style: TextStyle(
color: Colors.white,
),
),
),
),
height: 50,
)
: Container(
width: MediaQuery.of(context).size.width,
height: 50,
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

585
lib/Pages/Sub_Pages/Posts/SpecialPosts.dart

@ -1,585 +0,0 @@
import 'dart:typed_data';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flare_flutter/flare_controls.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:page_transition/page_transition.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/CouponDetails.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Classes/API%20Clasess/PostFav.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/Pages/Sub_Pages/Posts/comment.dart';
import 'package:teso/Pages/Sub_Pages/userProfile3P.dart';
import 'package:teso/Services/video_controller_service.dart';
import 'package:teso/blocs/video_player/video_player_bloc.dart';
import 'package:teso/blocs/video_player/video_player_event.dart';
import 'package:teso/blocs/video_player/video_player_state.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:teso/util/consts.dart';
import 'package:numeral/numeral.dart';
import 'package:teso/GeneralWidgets/widgets/video_player_widget.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
// ignore: must_be_immutable
class ViewPost extends StatefulWidget {
Post postedAd;
TesoUser user;
bool friend;
final bool play;
ViewPost({
Key key,
this.postedAd,
this.user,
this.friend,
@required this.play,
// this.posts,
}) : super(key: key);
@override
_ViewPostState createState() => _ViewPostState();
}
class _ViewPostState extends State<ViewPost> {
bool favoured = false;
List<CouponDetails> coupons = <CouponDetails>[];
Uint8List imageBitmap;
final FlareControls flareControls = FlareControls();
bool campaignAd = false;
int likes = 0;
int comments = 0;
var userDoc;
var document;
void sharing(Post ad) async {
await rootBundle
.load("assets/images/rawLogoOverlay.png")
.then((value) => setState(() {
imageBitmap = value.buffer.asUint8List();
}));
Provider.of<UserProvider>(context, listen: false).downloadVideo(
ad.postID, ad.playbackID, ad.rendition, imageBitmap, context);
}
@override
void dispose() {
rootBundle.evict("assets/images/rawLogoOverlay.png");
super.dispose();
}
void likePost(Post ad) {
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
PostFav liked = new PostFav();
liked.admirerId = cid;
liked.countId = DateTime.now().toString() + "$cid";
liked.timestamp = DateTime.now().toIso8601String();
liked.postId = ad.postID;
setState(() {
// ad.likes.add(liked);
likes++;
favoured = true;
});
flareControls.play("like");
Provider.of<UserProvider>(context, listen: false).addLike(liked);
});
}
void dislikePost(Post ad) {
setState(() {
favoured = false;
likes--;
});
Provider.of<UserProvider>(context, listen: false).deleteLike(ad.postID);
}
void commentsDialog(BuildContext context) {
if (userDoc == null) {
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
setState(() {
userDoc = value.data();
});
});
} else {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
),
builder: (BuildContext bc) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
child: CommentSection(
postedAd: widget.postedAd,
user: TesoUser(
username: userDoc["username"],
userGUID: userDoc["id"],
)),
);
},
);
}
}
Future<void> getCampaignCoupons(String campaign) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Authorization': prefs.getString('tokensTeso')
};
try {
var register2 = serverLocation + 'coupons/campaign_coupons';
var client1 = await http.post(
Uri.parse(register2),
headers: requestHeaders,
body: json.encode(campaign),
);
if (client1.statusCode == 200) {
var details = jsonDecode(client1.body);
setState(() {
coupons = List<CouponDetails>.from(
details.map((model) => CouponDetails.fromJSON(model)).toList());
// coupons.removeWhere(
// (element) => element.expiration.isAfter(DateTime.now()));
});
}
} catch (e) {
print(e);
}
}
@override
void initState() {
campaignAd = false;
_getDocuments();
_likedListen();
_commentsListen();
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
if (mounted)
setState(() {
userDoc = value.data();
});
});
super.initState();
}
_getDocuments() {
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.get()
.then((value) {
if (mounted)
setState(() {
document = value.data();
if (document != null) {
if (document["campaignId"] != null) {
campaignAd = true;
getCampaignCoupons(document["campaignId"]);
}
}
});
});
}
_likedListen() {
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.collection("likes")
.snapshots()
.listen((event) {
if (mounted) {
setState(() {
favoured =
event.docs.any((element) => element.data()["admirerID"] == cid);
likes = event.docs.length;
});
}
});
});
}
_commentsListen() {
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.collection("comments")
.snapshots()
.listen((event) {
if (mounted) {
setState(() {
comments = event.docs.length;
});
}
});
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Stack(
children: [
_buildVideoPlayer(widget.postedAd),
Align(
alignment: Alignment.bottomRight,
child: Container(
margin: EdgeInsets.only(
right: 10,
bottom: 30,
),
width: 50,
height: MediaQuery.of(context).size.width * 0.73,
child: Column(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: InkWell(
onTap: widget.postedAd.publisherID != null
? () => Navigator.pushReplacement(
context,
PageTransition(
child: UserProfileThirdPerson(
user: new TesoUser(
username: userDoc["username"],
userGUID: userDoc["id"],
firstname: userDoc["firstname"],
lastname: userDoc["surname"],
),
),
type: PageTransitionType.fade,
),
)
: null,
child: CachedNetworkImage(
imageUrl: serverLocation +
"api/pulldp/" +
widget.postedAd.publisherID,
imageBuilder: (context, imageProvider) =>
FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: imageProvider,
placeholder:
AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
child: InkWell(
onTap: () {
if (campaignAd) {
if (favoured) {
return null;
} else {
likePost(widget.postedAd);
}
} else {
if (favoured) {
dislikePost(widget.postedAd);
} else {
likePost(widget.postedAd);
}
}
},
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.favorite,
size: 30,
color: favoured ? Colors.red : Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(likes).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
child: InkWell(
onTap: () => commentsDialog(context),
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.comment,
size: 30,
color: Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(comments).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
),
SizedBox(
height: 20,
),
Container(
height: 30,
child: InkWell(
onTap: () => sharing(widget.postedAd),
child: Icon(
Icons.share,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: MediaQuery.of(context).size.height * 0.05,
),
child: new Wrap(
direction: Axis.vertical,
children: [
new RichText(
maxLines: 5,
text: TextSpan(
text: userDoc != null ? "@" + userDoc["username"] : "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(height: 5),
Container(
margin: EdgeInsets.only(bottom: 20),
width: MediaQuery.of(context).size.width * 0.7,
child: Text(
document != null
? document["title"] != null
? document["title"]
: ""
: "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
height: 1.5,
),
maxLines: 4,
overflow: TextOverflow.ellipsis,
textDirection: TextDirection.rtl,
textAlign: TextAlign.left,
),
),
],
),
),
),
Align(
alignment: Alignment.topLeft,
child: Container(
margin: EdgeInsets.only(top: 25),
child: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: new Icon(
Icons.arrow_back,
color: Colors.white,
size: 25.0,
),
),
),
),
],
),
),
);
}
Widget _buildVideoPlayer(Post ad) {
return BlocProvider<VideoPlayerBloc>(
create: (context) => VideoPlayerBloc(
RepositoryProvider.of<VideoControllerService>(context))
..add(VideoSelectedEvent(ad)),
child: BlocBuilder<VideoPlayerBloc, VideoPlayerState>(
builder: (context, state) {
return Container(child: _getPlayer(context, state, ad));
},
),
);
}
Widget _getPlayer(BuildContext context, VideoPlayerState state, Post ad) {
// final screenWidth = MediaQuery.of(context).size.width;
// final containerHeight = screenWidth / ASPECT_RATIO;
final containerHeight = MediaQuery.of(context).size.height;
if (state is VideoPlayerStateLoaded) {
return GestureDetector(
onDoubleTap: () {
if (campaignAd) {
if (favoured) {
return null;
} else {
likePost(ad);
}
} else {
if (favoured) {
dislikePost(ad);
} else {
likePost(ad);
}
}
},
child: Stack(
children: [
VideoPlayerWidget(
key: Key(state.video.playbackID),
controller: state.controller,
ad: ad,
play: widget.play,
details: coupons,
),
Container(
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: Center(
child: SizedBox(
width: 80,
height: 80,
child: FlareActor(
'assets/like.flr',
controller: flareControls,
animation: 'idle',
),
),
),
),
],
),
);
}
if (state is VideoPlayerStateLoading) {
return Container(
height: containerHeight,
color: Colors.black,
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
);
}
if (state is VideoPlayerStateError) {
return Container(
height: containerHeight,
color: Colors.black,
child: Center(
child: Text(state.message),
),
);
}
return Container(
height: containerHeight,
color: Colors.black,
child: Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
),
);
}
}

515
lib/Pages/Sub_Pages/Posts/UserPosts.dart

@ -1,515 +0,0 @@
import 'dart:typed_data';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Classes/API%20Clasess/PostFav.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/Pages/Sub_Pages/Posts/deletePost.dart';
import 'package:teso/Services/uservideo_controller_service.dart';
import 'package:teso/blocs/video_player/uservideo_player_bloc.dart';
import 'package:teso/blocs/video_player/uservideo_player_event.dart';
import 'package:teso/blocs/video_player/uservideo_player_state.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:numeral/numeral.dart';
import 'package:teso/GeneralWidgets/widgets/uservideo_player_widget.dart';
import 'comment.dart';
// ignore: must_be_immutable
class UserPosts extends StatefulWidget {
FBPosts postedAd;
UserPosts({Key key, this.postedAd}) : super(key: key);
@override
_UserPostsState createState() => _UserPostsState();
}
class _UserPostsState extends State<UserPosts> {
bool favoured = false;
Uint8List imageBitmap;
var document;
var userDoc;
bool likeShow = false;
void sharing() async {
await rootBundle
.load("assets/images/rawLogoOverlay.png")
.then((value) => setState(() {
imageBitmap = value.buffer.asUint8List();
}));
Provider.of<UserProvider>(context, listen: false).downloadVideo(
widget.postedAd.postID,
widget.postedAd.playbackID,
widget.postedAd.rendition,
imageBitmap,
context);
}
@override
void dispose() {
rootBundle.evict("assets/images/rawLogoOverlay.png");
super.dispose();
}
void commentsDialog(BuildContext context) {
if (userDoc == null) {
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
setState(() {
userDoc = value.data();
});
});
} else {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
),
builder: (BuildContext bc) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
child: CommentSection(
postedAd: new Post(
aspect: widget.postedAd.aspect,
assetID: widget.postedAd.assetID,
playbackID: widget.postedAd.playbackID,
postID: widget.postedAd.postID,
publisherID: widget.postedAd.publisherID,
title: widget.postedAd.title,
rendition: widget.postedAd.rendition,
timestamp: widget.postedAd.timestamp,
),
user: TesoUser(
username: userDoc["username"],
userGUID: userDoc["id"],
)),
);
},
);
}
}
void likePost() {
setState(() {
likeShow = true;
});
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
PostFav liked = new PostFav();
liked.admirerId = cid;
liked.countId = DateTime.now().toString() + "$cid";
liked.timestamp = DateTime.now().toIso8601String();
liked.postId = widget.postedAd.postID;
setState(() {
widget.postedAd.likes++;
favoured = true;
});
Provider.of<UserProvider>(context, listen: false).addLike(liked);
});
}
void dislikePost() {
SharedPreferences.getInstance().then((value) {
// String cid = value.getString("id");
setState(() {
widget.postedAd.likes--;
favoured = false;
});
Provider.of<UserProvider>(context, listen: false)
.deleteLike(widget.postedAd.postID);
});
}
@override
void initState() {
super.initState();
_likedListen();
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.get()
.then((value) {
setState(() {
document = value.data();
});
});
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
setState(() {
userDoc = value.data();
});
});
// SharedPreferences.getInstance().then((value) {
// String cid = value.getString("id");
// if (widget.postedAd.likes
// .map((e) => e.admirerId)
// .toList()
// .contains(cid)) {
// setState(() {
// favoured = true;
// });
// }
// });
// _future = initializeController();
}
_likedListen() {
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.collection("likes")
.snapshots()
.listen((event) {
setState(() {
favoured =
event.docs.any((element) => element.data()["admirerID"] == cid);
widget.postedAd.likes = event.docs.length;
});
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
child: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
leading: _backWidget(context),
),
preferredSize: Size.fromHeight(40)),
extendBodyBehindAppBar: true,
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Stack(
children: [
_buildVideoPlayer(),
Align(
alignment: Alignment.bottomRight,
child: Container(
margin: EdgeInsets.only(
right: 10,
),
width: 50,
height: MediaQuery.of(context).size.width * 0.7,
child: Column(
children: [
_favoriteWidget(context),
SizedBox(
height: 20,
),
_commentWidget(context),
SizedBox(
height: 20,
),
Container(
height: 30,
child: InkWell(
onTap: () => sharing(),
child: Icon(
Icons.share,
size: 30,
color: Colors.white,
),
),
),
SizedBox(
height: 20,
),
_deleteWidget(context),
],
),
),
),
_nameDescription(context),
],
),
),
);
}
Widget _buildVideoPlayer() {
return BlocProvider<VideoPlayerBloc>(
create: (context) => VideoPlayerBloc(
RepositoryProvider.of<VideoControllerService>(context))
..add(VideoSelectedEvent(widget.postedAd)),
child: BlocBuilder<VideoPlayerBloc, VideoPlayerState>(
builder: (context, state) {
return Container(child: _getPlayer(context, state));
},
),
);
}
Widget _getPlayer(BuildContext context, VideoPlayerState state) {
// final screenWidth = MediaQuery.of(context).size.width;
// final containerHeight = screenWidth / ASPECT_RATIO;
if (state is VideoPlayerStateLoaded) {
return GestureDetector(
onDoubleTap: () {
if (widget.postedAd.campaignID != null) {
if (favoured) {
return null;
} else {
likePost();
}
} else {
if (favoured) {
dislikePost();
} else {
likePost();
}
}
},
child: Stack(
children: [
VideoPlayerWidget(
key: Key(state.video.playbackID),
controller: state.controller,
ad: widget.postedAd,
),
AnimatedOpacity(
opacity: likeShow ? 1 : 0,
duration: Duration(seconds: 2),
onEnd: () {
setState(() {
likeShow = false;
});
},
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: Center(
child: Image.asset("assets/lovw.gif"),
),
),
),
],
),
);
}
if (state is VideoPlayerStateLoading) {
return Container();
}
if (state is VideoPlayerStateError) {
return Container();
}
return Container();
}
Widget _favoriteWidget(BuildContext context) {
return Container(
height: 50,
child: InkWell(
onTap: () {
if (widget.postedAd.campaignID != null) {
if (favoured) {
return null;
} else {
likePost();
}
} else {
if (favoured) {
dislikePost();
} else {
likePost();
}
}
},
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.favorite,
size: 30,
color: favoured ? Colors.red : Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(widget.postedAd.likes).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
);
}
Widget _commentWidget(BuildContext context) {
return Container(
height: 50,
child: InkWell(
onTap: () => commentsDialog(context),
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.comment,
size: 30,
color: Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(widget.postedAd.comments).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
);
}
Widget _nameDescription(BuildContext context) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: MediaQuery.of(context).size.height * 0.05,
),
child: new Wrap(
direction: Axis.vertical,
children: [
new RichText(
maxLines: 5,
text: TextSpan(
text: userDoc != null
? userDoc["username"] != null
? "@" + userDoc["username"]
: ""
: "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(height: 5),
Container(
margin: EdgeInsets.only(bottom: 20),
width: MediaQuery.of(context).size.width * 0.7,
child: Text(
widget.postedAd.title != null ? widget.postedAd.title : "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
height: 1.5,
),
maxLines: 4,
overflow: TextOverflow.ellipsis,
textDirection: TextDirection.rtl,
textAlign: TextAlign.left,
),
),
],
),
),
);
}
Widget _deleteWidget(BuildContext context) {
return Container(
height: 30,
child: GestureDetector(
onTap: () async {
bool result = await Navigator.push(
context,
PageRouteBuilder(
opaque: false,
pageBuilder: (_, __, ___) => DeletePost(),
),
);
if (result) {
Provider.of<UserProvider>(context, listen: false).deletePost(Post(
aspect: widget.postedAd.aspect,
playbackID: widget.postedAd.playbackID,
postID: widget.postedAd.postID,
publisherID: widget.postedAd.publisherID,
assetID: widget.postedAd.assetID,
timestamp: widget.postedAd.timestamp,
title: widget.postedAd.title,
));
Navigator.pop(context);
}
},
child: Icon(
Icons.delete,
size: 28,
color: Colors.white,
),
),
);
}
Widget _backWidget(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: Colors.transparent,
),
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
);
}
}

920
lib/Pages/Sub_Pages/Posts/ViewPost.dart

@ -1,920 +0,0 @@
import 'dart:typed_data';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flare_flutter/flare_controls.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:page_transition/page_transition.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/CouponDetails.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Classes/API%20Clasess/PostFav.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/Pages/Sub_Pages/Posts/comment.dart';
import 'package:teso/Pages/Sub_Pages/userProfile3P.dart';
import 'package:teso/Services/video_controller_service.dart';
import 'package:teso/blocs/video_player/video_player_bloc.dart';
import 'package:teso/blocs/video_player/video_player_event.dart';
import 'package:teso/blocs/video_player/video_player_state.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:teso/util/consts.dart';
import 'package:numeral/numeral.dart';
import 'package:teso/GeneralWidgets/widgets/video_player_widget.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
// ignore: must_be_immutable
class ViewPost extends StatefulWidget {
Post postedAd;
TesoUser user;
bool friend;
final bool play;
Function report;
ViewPost({
Key key,
this.postedAd,
this.user,
this.friend,
@required this.play,
@required this.report,
// this.posts,
}) : super(key: key);
@override
_ViewPostState createState() => _ViewPostState();
}
class _ViewPostState extends State<ViewPost> {
bool favoured = false;
List<CouponDetails> coupons = <CouponDetails>[];
Uint8List imageBitmap;
final FlareControls flareControls = FlareControls();
bool campaignAd = false;
int likes = 0;
int comments = 0;
var userDoc;
var document;
bool likeShow = false;
bool dark = false;
void sharing(Post ad) async {
await rootBundle
.load("assets/images/rawLogoOverlay.png")
.then((value) => setState(() {
imageBitmap = value.buffer.asUint8List();
}));
Provider.of<UserProvider>(context, listen: false).downloadVideo(
ad.postID, ad.playbackID, ad.rendition, imageBitmap, context);
}
@override
void dispose() {
rootBundle.evict("assets/images/rawLogoOverlay.png");
super.dispose();
}
void likePost(Post ad) {
setState(() {
likeShow = true;
});
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
PostFav liked = new PostFav();
liked.admirerId = cid;
liked.countId = DateTime.now().toString() + "$cid";
liked.timestamp = DateTime.now().toIso8601String();
liked.postId = ad.postID;
setState(() {
// ad.likes.add(liked);
likes++;
favoured = true;
});
flareControls.play("like");
Provider.of<UserProvider>(context, listen: false).addLike(liked);
});
}
void dislikePost(Post ad) {
setState(() {
favoured = false;
likes--;
});
Provider.of<UserProvider>(context, listen: false).deleteLike(ad.postID);
}
void commentsDialog(BuildContext context) {
if (userDoc == null) {
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
setState(() {
userDoc = value.data();
});
});
} else {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
),
builder: (BuildContext bc) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
child: CommentSection(
postedAd: widget.postedAd,
user: TesoUser(
username: userDoc["username"],
userGUID: userDoc["id"],
)),
);
},
);
}
}
Future<void> getCampaignCoupons(String campaign) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Authorization': prefs.getString('tokensTeso')
};
try {
var register2 = serverLocation + 'coupons/campaign_coupons';
var client1 = await http.post(
Uri.parse(register2),
headers: requestHeaders,
body: json.encode(campaign),
);
if (client1.statusCode == 200) {
var details = jsonDecode(client1.body);
setState(() {
coupons = List<CouponDetails>.from(
details.map((model) => CouponDetails.fromJSON(model)).toList());
// coupons.removeWhere(
// (element) => element.expiration.isAfter(DateTime.now()));
});
}
} catch (e) {
print(e);
}
}
@override
void initState() {
campaignAd = false;
_getDocuments();
_likedListen();
_commentsListen();
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
if (mounted)
setState(() {
userDoc = value.data();
});
});
SharedPreferences.getInstance().then((value) =>
value.getString("theme") == "light" ? dark = false : dark = true);
super.initState();
}
_getDocuments() {
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.get()
.then((value) {
if (mounted)
setState(() {
document = value.data();
if (document != null) {
if (document["campaignId"] != null) {
campaignAd = true;
getCampaignCoupons(document["campaignId"]);
}
}
});
});
}
_likedListen() {
SharedPreferences.getInstance().then((value) {
String cid = value.getString("id");
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.collection("likes")
.snapshots()
.listen((event) {
if (mounted) {
setState(() {
favoured =
event.docs.any((element) => element.data()["admirerID"] == cid);
likes = event.docs.length;
});
}
});
});
}
_commentsListen() {
FirebaseFirestore.instance
.collection("posts")
.doc(widget.postedAd.postID)
.collection("comments")
.snapshots()
.listen((event) {
if (mounted) {
setState(() {
comments = event.docs.length;
});
}
});
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Stack(
children: [
_buildVideoPlayer(widget.postedAd),
Align(
alignment: Alignment.bottomRight,
child: Container(
margin: EdgeInsets.only(
right: 10,
bottom: 30,
),
width: 50,
height: MediaQuery.of(context).size.width * 0.73,
child: Column(
children: [
_publisherWidget(context),
SizedBox(
height: 20,
),
_favoriteWidget(context),
SizedBox(
height: 20,
),
_commentWidget(context),
SizedBox(
height: 20,
),
Container(
height: 30,
child: InkWell(
onTap: () => moreDialog(context, widget.postedAd),
child: Icon(
Icons.more_horiz,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
_nameDescription(context),
],
),
),
);
}
Widget _buildVideoPlayer(Post ad) {
return BlocProvider<VideoPlayerBloc>(
create: (context) => VideoPlayerBloc(
RepositoryProvider.of<VideoControllerService>(context))
..add(VideoSelectedEvent(ad)),
child: BlocBuilder<VideoPlayerBloc, VideoPlayerState>(
builder: (context, state) {
return Container(child: _getPlayer(context, state, ad));
},
),
);
}
Widget _getPlayer(BuildContext context, VideoPlayerState state, Post ad) {
// final screenWidth = MediaQuery.of(context).size.width;
// final containerHeight = screenWidth / ASPECT_RATIO;
final containerHeight = MediaQuery.of(context).size.height;
if (state is VideoPlayerStateLoaded) {
return GestureDetector(
onDoubleTap: () {
if (campaignAd) {
if (favoured) {
return null;
} else {
likePost(ad);
}
} else {
if (favoured) {
dislikePost(ad);
} else {
likePost(ad);
}
}
},
child: Stack(
children: [
VideoPlayerWidget(
key: Key(state.video.playbackID),
controller: state.controller,
ad: ad,
play: widget.play,
details: coupons,
),
AnimatedOpacity(
opacity: likeShow ? 1 : 0,
duration: Duration(seconds: 2),
onEnd: () {
setState(() {
likeShow = false;
});
},
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: Center(
child: Image.asset("assets/lovw.gif"),
),
),
),
],
),
);
}
if (state is VideoPlayerStateLoading) {
return Container();
}
if (state is VideoPlayerStateError) {
return Container(
height: containerHeight,
color: Colors.black,
child: Center(
child: Text(state.message),
),
);
}
return Container();
}
Widget _nameDescription(BuildContext context) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: MediaQuery.of(context).size.height * 0.05,
),
child: new Wrap(
direction: Axis.vertical,
children: [
new RichText(
maxLines: 5,
text: TextSpan(
text: userDoc != null ? "@" + userDoc["username"] : "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(height: 5),
Container(
margin: EdgeInsets.only(bottom: 20),
width: MediaQuery.of(context).size.width * 0.7,
child: Text(
document != null
? document["title"] != null
? document["title"]
: ""
: "",
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.safeBlockHorizontal * 4.3,
height: 1.5,
),
maxLines: 4,
overflow: TextOverflow.ellipsis,
textDirection: TextDirection.rtl,
textAlign: TextAlign.left,
),
),
],
),
),
);
}
Widget _publisherWidget(BuildContext context) {
return Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: InkWell(
onTap: widget.postedAd.publisherID != null
? () => Navigator.pushReplacement(
context,
PageTransition(
child: UserProfileThirdPerson(
user: new TesoUser(
username: userDoc["username"],
userGUID: userDoc["id"],
firstname: userDoc["firstname"],
lastname: userDoc["surname"],
),
),
type: PageTransitionType.fade,
),
)
: null,
child: CachedNetworkImage(
imageUrl:
serverLocation + "api/pulldp/" + widget.postedAd.publisherID,
imageBuilder: (context, imageProvider) => FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: imageProvider,
placeholder: AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
),
);
}
Widget _favoriteWidget(BuildContext context) {
return Container(
height: 50,
child: InkWell(
onTap: () {
if (campaignAd) {
if (favoured) {
return null;
} else {
likePost(widget.postedAd);
}
} else {
if (favoured) {
dislikePost(widget.postedAd);
} else {
likePost(widget.postedAd);
}
}
},
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.favorite,
size: 30,
color: favoured ? Colors.red : Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(likes).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
);
}
Widget _commentWidget(BuildContext context) {
return Container(
height: 50,
child: InkWell(
onTap: () => commentsDialog(context),
child: new Wrap(
direction: Axis.vertical,
children: [
Container(
width: 50,
height: 30,
child: Center(
child: Icon(
Icons.comment,
size: 30,
color: Colors.white,
),
),
),
Container(
height: 20,
width: 50,
child: Center(
child: Text(
Numeral(comments).value().toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
);
}
void moreDialog(BuildContext context, Post ad) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(30.0)),
),
builder: (BuildContext bc) {
return Container(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: new Wrap(
children: <Widget>[
new Container(
margin: EdgeInsets.symmetric(
vertical: 15.0,
),
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Container(
width: 50,
height: 4,
color: Colors.grey,
),
),
),
),
buildTop3(context, ad),
new Container(
width: MediaQuery.of(context).size.width,
height: 40,
margin: EdgeInsets.symmetric(vertical: 20.0, horizontal: 15),
decoration: BoxDecoration(
color: !dark ? Colors.grey[200] : Colors.white12,
borderRadius: BorderRadius.circular(5)),
child: new Center(
child: Text(
"Why you're seeing this post",
textAlign: TextAlign.center,
style: TextStyle(
color: !dark ? Colors.black : Colors.white,
),
),
),
),
// bottomButtons(context, friends),
],
),
),
);
},
);
}
buildTop3(BuildContext context, Post ad) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTap: () => sharing(ad),
child: Container(
width: SizeConfig.blockSizeHorizontal * 30,
height: SizeConfig.blockSizeHorizontal * 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(
10,
),
),
color: !dark ? Colors.grey[200] : Colors.white12,
),
alignment: Alignment.center,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(Icons.share),
Text(
"Share",
),
],
),
),
),
),
GestureDetector(
onTap: () => reportDialog(context),
child: Container(
width: SizeConfig.blockSizeHorizontal * 30,
height: SizeConfig.blockSizeHorizontal * 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(
10,
),
),
color: !dark ? Colors.grey[200] : Colors.white12,
),
alignment: Alignment.center,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
Icons.report_problem,
color: Colors.red[900],
),
Text(
"Report",
),
],
),
),
),
),
],
);
}
flagContent(level) {
Provider.of<UserProvider>(context, listen: false)
.flagPost(widget.postedAd, level);
Navigator.pop(context);
widget.report(widget.postedAd);
this.dispose();
}
bottomButtons(BuildContext context, friends) {
return new Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 15),
child: Column(
children: [
new Container(
width: MediaQuery.of(context).size.width,
child: new Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.grey[200],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
onPressed: () => Navigator.pop(context),
child: Container(
width: MediaQuery.of(context).size.width,
child: Text(
"Hide",
textAlign: TextAlign.center,
)),
),
),
),
friends
? new Container(
width: MediaQuery.of(context).size.width,
child: new Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
onPressed: () => Navigator.pop(context),
child: Container(
width: MediaQuery.of(context).size.width,
child: Text(
"Unfrend",
textAlign: TextAlign.center,
)),
),
),
)
: new Container(
width: MediaQuery.of(context).size.width,
child: new Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
onPressed: () => Navigator.pop(context),
child: Container(
width: MediaQuery.of(context).size.width,
child: Text(
"Add Friend",
textAlign: TextAlign.center,
)),
),
),
)
],
));
}
void reportDialog(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(30.0)),
),
builder: (BuildContext bc) {
return Container(
height: MediaQuery.of(context).size.height * 0.95,
child: Column(
children: [
new Container(
margin: EdgeInsets.symmetric(
vertical: 15.0,
),
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Container(
width: 50,
height: 4,
color: Colors.grey,
),
),
),
),
Container(
child: Center(
child: Text(
"Report",
style: TextStyle(
fontSize: SizeConfig.blockSizeHorizontal * 3.5,
fontWeight: FontWeight.w800,
),
),
),
),
Divider(),
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(
"Why are you reporting this post?",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: SizeConfig.blockSizeHorizontal * 3.5,
fontWeight: FontWeight.w800,
),
),
),
SizedBox(
height: 5,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Center(
child: Text(
"Your report would be handled as soon as possible. However if someone is in immediate danger, call the local emergency services - don't wait.",
style: TextStyle(
fontSize: SizeConfig.blockSizeHorizontal * 3.5,
fontWeight: FontWeight.w400,
),
),
),
),
Divider(),
Container(
height: MediaQuery.of(context).size.height * 0.7,
child: new ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
ListTile(
title: Text("It's a spam"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(1),
),
ListTile(
title: Text("Nudity or sexual activity"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(2),
),
ListTile(
title: Text("I just don't like it"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(3),
),
ListTile(
title: Text("Hate speech or symbols"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(4),
),
ListTile(
title: Text("False information"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(5),
),
ListTile(
title: Text("Bullying harassment"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(6),
),
ListTile(
title: Text("Violence or dangerous organisations"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(7),
),
ListTile(
title: Text("Scam or fraud"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(8),
),
ListTile(
title: Text("Intellectual property violation"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(9),
),
ListTile(
title: Text("Sale of illegal or regulated goods"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(10),
),
ListTile(
title: Text("Suicide or self-injury"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(11),
),
ListTile(
title: Text("Eating disorders"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () => flagContent(12),
),
],
),
),
],
),
);
},
);
}
}

332
lib/Pages/Sub_Pages/Posts/comment.dart

@ -1,332 +0,0 @@
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Classes/Firebase/Comments.dart';
import 'package:teso/Classes/TesoUser.dart';
import 'package:teso/Pages/PageWidgets/Posts/user3P_commentTitle.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/CommentsPost.dart';
import 'package:teso/Pages/PageWidgets/ChatScreen/bottomBar.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:intl/intl.dart';
import 'package:time_elapsed/time_elapsed.dart';
class CommentSection extends StatefulWidget {
final Post postedAd;
final TesoUser user;
CommentSection({
Key key,
@required this.postedAd,
@required this.user,
}) : assert(postedAd != null),
assert(user != null),
super(key: key);
@override
_CommentSectionState createState() => _CommentSectionState();
}
class _CommentSectionState extends State<CommentSection> {
TextEditingController controller = new TextEditingController();
final ScrollController listScrollController = ScrollController();
List<FBComments> listMessage = <FBComments>[];
int _limit = 20;
final int _limitIncrement = 20;
int total = 0;
var userDocs;
List<FBComments> latest = <FBComments>[];
_scrollListener() {
if (listScrollController.offset >=
listScrollController.position.maxScrollExtent &&
!listScrollController.position.outOfRange) {
print("reach the bottom");
setState(() {
print("reach the bottom");
_limit += _limitIncrement;
});
}
if (listScrollController.offset <=
listScrollController.position.minScrollExtent &&
!listScrollController.position.outOfRange) {
print("reach the top");
setState(() {
print("reach the top");
});
}
}
@override
void initState() {
super.initState();
listScrollController.addListener(_scrollListener);
_listenComments();
FirebaseFirestore.instance
.collection("users")
.doc(widget.postedAd.publisherID)
.get()
.then((value) {
setState(() {
userDocs = value.data();
});
});
}
@override
void dispose() {
controller.dispose();
listScrollController.dispose();
super.dispose();
}
void sendComment(String text, int position) async {
TesoUser user =
Provider.of<UserProvider>(context, listen: false).currentUser;
if (controller.text.isNotEmpty) {
CommentsPost comment = new CommentsPost();
SharedPreferences.getInstance().then((value) async {
comment.postId = widget.postedAd.postID;
comment.comment = text.trim();
comment.timestamp = DateTime.now().toIso8601String();
comment.commenterId = value.getString("id");
comment.commentId =
"TESCPCM" + DateTime.now().toString() + value.getString("id");
setState(() {
latest.add(FBComments(
comment: comment.comment,
commenterID: comment.commenterId,
commentID: comment.commentId,
commenter: user.username,
postID: comment.postId,
thumbnail: user.thumbnail_dp,
timestamp: DateTime.now(),
));
total++;
});
});
Provider.of<UserProvider>(context, listen: false).commentPost(comment);
controller.clear();
}
}
_listenComments() {
FirebaseFirestore.instance
.collection('posts')
.doc(widget.postedAd.postID)
.collection("comments")
.orderBy('timestamp')
.snapshots()
.listen((event) {
if (mounted) {
setState(() {
total = event.docs.length;
latest.clear();
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
title: Text(
"$total comments",
style: TextStyle(
fontSize: 14,
),
),
actions: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: Icon(
Icons.close,
),
),
],
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.only(bottom: 60),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(widget.postedAd.postID)
.collection("comments")
.orderBy('timestamp')
.limit(_limit)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryColor)));
} else if (snapshot.data.docs.length == 0) {
if (widget.postedAd.title != null) {
return Align(
alignment: Alignment.topCenter,
child: buildPostTile3P(
context, widget.user, widget.postedAd),
);
} else {
return Container();
}
} else {
QuerySnapshot results = snapshot.data;
listMessage = results.docs
.map((e) => FBComments.fromJSON(e.data()))
.toList();
if (latest.length != 0) {
listMessage.addAll(latest);
}
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemCount: listMessage.length,
itemBuilder: (context, index) {
var formattedDate = DateFormat("yyyy-MM-dd HH:mm:ss")
.format(listMessage[index].timestamp);
if (index == 0 && widget.postedAd.title != null) {
return Column(children: [
buildPostTile3P(
context, widget.user, widget.postedAd),
Divider(),
ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(serverLocation +
"api/pulldp/" +
snapshot.data.docs[index]
.data()['commenterID']),
placeholder: AssetImage(
"assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: snapshot.data.docs[index]
.data()['commenter'] +
" ",
style: new TextStyle(
fontWeight: FontWeight.bold)),
new TextSpan(
text: snapshot.data.docs[index]
.data()['comment']),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(
DateTime.parse(formattedDate)),
),
),
]);
}
return ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(serverLocation +
"api/pulldp/" +
listMessage[index].commenterID),
placeholder:
AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: listMessage[index].commenter + " ",
style: new TextStyle(
fontWeight: FontWeight.bold)),
new TextSpan(text: listMessage[index].comment),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(
DateTime.parse(formattedDate)),
),
);
},
// reverse: true,
controller: listScrollController,
);
}
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: buildBottom(
context,
controller,
sendComment,
),
),
],
),
),
);
}
}

155
lib/Pages/Sub_Pages/Posts/deletePost.dart

@ -1,155 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/util/SizeConfig.dart';
import 'package:teso/util/consts.dart';
class DeletePost extends StatefulWidget {
final Post post;
const DeletePost({Key key, this.post}) : super(key: key);
@override
_DeletePostState createState() => _DeletePostState();
}
class _DeletePostState extends State<DeletePost> {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
backgroundColor: Color.fromRGBO(0, 0, 0, 0.5),
body: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.symmetric(
vertical: SizeConfig.blockSizeHorizontal * 5,
),
width: MediaQuery.of(context).size.width,
height: SizeConfig.blockSizeHorizontal * 52.6,
child: Column(
children: [
_descriptionBox(context),
SizedBox(
height: 5,
),
_cancelDelete(context),
],
),
),
),
],
),
);
}
Widget _descriptionBox(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: Material(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
children: [
SizedBox(
height: 5,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: SizeConfig.safeBlockHorizontal * 2),
padding: EdgeInsets.symmetric(
horizontal: SizeConfig.safeBlockHorizontal * 6),
alignment: Alignment.center,
child: Text(
"Once you proceed you cannot undo your actions . " +
"Are you sure you would like to delete this post ? ",
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).colorScheme.secondary ==
Color(0xFFfd0a35)
? Colors.white24
: tesoBlue),
),
),
SizedBox(
height: 10,
),
Divider(),
SizedBox(
height: 10,
),
InkWell(
onTap: () => Navigator.pop(context, true),
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
child: Text(
"Delete",
style: TextStyle(
color: Colors.red,
fontSize: SizeConfig.safeBlockHorizontal * 4.0,
fontWeight: FontWeight.bold,
),
),
),
),
SizedBox(
height: 10,
),
],
),
),
),
),
);
}
Widget _cancelDelete(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: SizeConfig.safeBlockVertical * 6.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: ColorFiltered(
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.1), BlendMode.lighten),
child: Material(
child: Container(
padding: EdgeInsets.all(10),
child: InkWell(
onTap: () => Navigator.pop(context, false),
child: Text(
"Cancel",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blueAccent,
fontSize: SizeConfig.safeBlockHorizontal * 4.5,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
),
);
}
}

103
lib/Pages/Sub_Pages/Posts/postedDetails.dart

@ -1,103 +0,0 @@
// import 'dart:typed_data';
// import 'package:teso/Classes/API%20Clasess/PostedAd.dart';
// import 'package:teso/Pages/PageWidgets/Posts/comment.dart';
// import 'package:teso/Pages/PageWidgets/Posts/expandedPost.dart';
// import 'package:flutter/material.dart';
//
// import 'package:teso/util/consts.dart';
// import 'package:video_player/video_player.dart';
// class PostDetails extends StatefulWidget {
// final PostedAd type;
// const PostDetails({Key key, this.type}) : super(key: key);
// @override
// _PostDetailsState createState() => _PostDetailsState(post: type);
// }
// class _PostDetailsState extends State<PostDetails> {
// PostedAd post;
// _PostDetailsState({this.post});
// bool available = false;
// Uint8List bytes;
// TextEditingController controller;
// VideoPlayerController _videoPlayerController;
// void deleteDialog(context) {
// showModalBottomSheet(
// context: context,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.vertical(top: Radius.circular(30.0)),
// ),
// builder: (BuildContext bc) {
// return Container(
// child: new Wrap(
// children: <Widget>[
// new Container(
// width: double.infinity,
// margin: EdgeInsets.only(
// top: 20.0,
// bottom: 12.0,
// ),
// child: Center(
// child: Text(
// "Delete post",
// style: TextStyle(
// fontSize: 12.0,
// ),
// ),
// )),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Divider(),
// ),
// new ListTile(
// leading: new Icon(MaterialCommunityIcons.trash_can),
// title: new Text('Delete'),
// onTap: () => print("Delete")),
// ],
// ),
// );
// },
// );
// }
// @override
// void initState() {
// super.initState();
// _videoPlayerController =
// VideoPlayerController.network(tesoStreaming + post.post.path)
// ..initialize().then((_) {
// _videoPlayerController.play();
// _videoPlayerController.setLooping(true);
// setState(() {});
// });
// }
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: null,
// body: Container(
// margin: EdgeInsets.only(
// top: 50,
// left: 10,
// right: 10,
// ),
// height: MediaQuery.of(context).size.height,
// width: MediaQuery.of(context).size.width,
// child: SingleChildScrollView(
// scrollDirection: Axis.vertical,
// child: Column(
// children: [
// buildPostDetails(
// context, post, deleteDialog, _videoPlayerController),
// Padding(padding: EdgeInsets.all(05)),
// buildCommentTile(context, available, bytes, controller),
// ],
// ),
// ),
// ),
// );
// }
// }

289
lib/Pages/Sub_Pages/Posts/user_comment.dart

@ -1,289 +0,0 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/CommentsPost.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
import 'package:teso/Pages/PageWidgets/ChatScreen/bottomBar.dart';
import 'package:teso/Pages/Sub_Pages/Posts/UserPosts.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:teso/util/consts.dart';
import 'package:intl/intl.dart';
import 'package:time_elapsed/time_elapsed.dart';
// ignore: must_be_immutable
class CommentSection extends StatefulWidget {
FBPosts postedAd;
CommentSection({
Key key,
@required this.postedAd,
}) : assert(postedAd != null),
super(key: key);
@override
_CommentSectionState createState() => _CommentSectionState();
}
class _CommentSectionState extends State<CommentSection> {
TextEditingController controller = new TextEditingController();
final ScrollController listScrollController = ScrollController();
List<QueryDocumentSnapshot> listMessage = new List.from([]);
int _limit = 20;
final int _limitIncrement = 20;
_scrollListener() {
if (listScrollController.offset >=
listScrollController.position.maxScrollExtent &&
!listScrollController.position.outOfRange) {
print("reach the bottom");
setState(() {
print("reach the bottom");
_limit += _limitIncrement;
});
}
if (listScrollController.offset <=
listScrollController.position.minScrollExtent &&
!listScrollController.position.outOfRange) {
print("reach the top");
setState(() {
print("reach the top");
});
}
}
@override
void initState() {
super.initState();
listScrollController.addListener(_scrollListener);
}
@override
void dispose() {
controller.dispose();
listScrollController.dispose();
super.dispose();
}
void sendComment(String text, int position) async {
if (controller.text.isNotEmpty) {
CommentsPost comment = new CommentsPost();
SharedPreferences.getInstance().then((value) async {
comment.postId = widget.postedAd.postID;
comment.comment = text;
comment.timestamp = DateTime.now().toIso8601String();
comment.commenterId = value.getString("id");
comment.commentId =
"TESCPCM" + DateTime.now().toString() + value.getString("id");
});
// setState(() {
// widget.postedAd.comments.add(comment);
// });
Provider.of<UserProvider>(context, listen: false).commentPost(comment);
controller.clear();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Comments"),
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
),
onPressed: () => Navigator.pushReplacement(
context,
PageTransition(
child: UserPosts(
postedAd: widget.postedAd,
),
type: PageTransitionType.rightToLeft,
),
),
),
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.only(bottom: 60),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('posts')
.doc('comments')
.collection(widget.postedAd.postID)
.orderBy('timestamp')
.limit(_limit)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data == null &&
snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryColor)));
} else if (snapshot.data.docs.length == 0) {
// if (widget.postedAd.title != null) {
// return Align(
// alignment: Alignment.topCenter,
// child: buildPostTile(context, widget.postedAd),
// );
// } else {
return Container();
// }
} else {
listMessage = snapshot.data.docs;
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemCount: listMessage.length,
itemBuilder: (context, index) {
int timeInMillis = int.parse(snapshot.data.docs[index]
.data()['timestamp']
.toString());
var date =
DateTime.fromMillisecondsSinceEpoch(timeInMillis);
var formattedDate =
DateFormat("yyyy-MM-dd HH:mm:ss").format(date);
if (index == 0 && widget.postedAd.title != null) {
return Column(children: [
// buildPostTile(context, widget.postedAd),
Divider(),
ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(serverLocation +
"api/pulldp/" +
snapshot.data.docs[index]
.data()['commenterID']),
placeholder: AssetImage(
"assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: snapshot.data.docs[index]
.data()['commenter'] +
" ",
style: new TextStyle(
fontWeight: FontWeight.bold)),
new TextSpan(
text: snapshot.data.docs[index]
.data()['comment']),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(
DateTime.parse(formattedDate)),
),
),
]);
}
return ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1,
)),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(90.0),
topRight: Radius.circular(90.0),
bottomLeft: Radius.circular(90),
bottomRight: Radius.circular(90),
),
child: FadeInImage(
height: 90,
width: 90,
fit: BoxFit.fill,
image: NetworkImage(serverLocation +
"api/pulldp/" +
snapshot.data.docs[index]
.data()['commenterID']),
placeholder:
AssetImage("assets/images/tesoDP/dp1.png"),
),
),
),
title: new RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryColorLight,
),
children: <TextSpan>[
new TextSpan(
text: snapshot.data.docs[index]
.data()['commenter'] +
" ",
style: new TextStyle(
fontWeight: FontWeight.bold)),
new TextSpan(
text: snapshot.data.docs[index]
.data()['comment']),
],
),
),
subtitle: Text(
TimeElapsed.fromDateTime(
DateTime.parse(formattedDate)),
),
);
},
// reverse: true,
controller: listScrollController,
);
}
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: buildBottom(
context,
controller,
sendComment,
),
),
],
),
),
);
}
}

204
lib/Pages/Sub_Pages/homeSub/HomeFeed.dart

@ -1,204 +0,0 @@
import 'dart:convert';
import 'dart:math';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Pages/PageWidgets/Home/homeTile.dart';
import 'package:teso/Pages/Sub_Pages/homeSub/VideoList.dart';
import 'package:teso/util/consts.dart';
class HomeFeed extends StatefulWidget {
@override
_HomeFeedState createState() => _HomeFeedState();
}
class _HomeFeedState extends State<HomeFeed> {
ScrollController _controller;
// List<PostedAd> trends;
List<Post> show;
int count;
var _future;
List<Post> deadFeed;
RefreshController _refreshController =
RefreshController(initialRefresh: false);
Future<List<Post>> pullAds() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("tokensTeso");
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Authorization': token
};
var register = serverLocation + 'posts/homefeed';
var client =
await http.post(Uri.parse(register), headers: requestHeaders);
if (client.statusCode == 200) {
var posts = jsonDecode(client.body);
setState(() {
this.show = List<Post>.from(
posts.map((model) => Post.fromJSON(model)).toList());
// this.show.sort((b, a) => a.timestamp.compareTo(b.timestamp));
});
await prefs.setString("homefeeds", client.body);
// await fetchImages();
//
return show;
} else {
return null;
}
} catch (e) {
return null;
}
}
void _scrollListener() {
if (_controller.offset >= _controller.position.maxScrollExtent &&
!_controller.position.outOfRange) {
pullAds();
}
}
void _onRefresh() async {
try {
await pullAds();
} catch (e) {
print(e);
}
_refreshController.refreshCompleted();
}
Future<void> watch(advert) async {
List<Post> towatch = <Post>[];
towatch.add(advert);
if (show.length != 0) {
for (int i = 0; (i < show.length) && (i < 10); i++) {
final _random = new Random();
towatch.add(show[_random.nextInt(show.length)]);
}
} else if (show.length == 0) {
for (int i = 0; (i < deadFeed.length) && (i < 10); i++) {
final _random = new Random();
towatch.add(deadFeed[_random.nextInt(show.length)]);
}
}
Post reported = await Navigator.of(context).push(
new PageRouteBuilder(
pageBuilder: (_, __, ___) => new VideoList(
postedAd: towatch,
// posts: towatch,
// user: user,
//friend: addable,
),
),
);
if (reported != null) {
show.remove(reported);
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString("homefeeds", jsonEncode(show));
print(prefs.getString("homefeed"));
}
}
@override
void initState() {
// WidgetsBinding.instance.addPostFrameCallback((_) => widget.toggle(1));
_controller = ScrollController();
_controller.addListener(_scrollListener);
count = 0;
// pullAds();
SharedPreferences.getInstance().then((value) {
if (value.getString("homefeeds") != null) {
var posts = jsonDecode(value.getString("homefeeds"));
setState(() {
deadFeed = List<Post>.from(
posts.map((model) => Post.fromJSON(model)).toList());
});
}
});
_future = pullAds();
super.initState();
}
@override
void dispose() {
_controller.dispose();
_refreshController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
initialData: deadFeed,
future: _future,
builder: (context, snapshot) {
if (show == null &&
deadFeed == null &&
(snapshot.connectionState == ConnectionState.none ||
snapshot.connectionState == ConnectionState.waiting)) {
return Center(
child: CupertinoActivityIndicator(
animating: true,
radius: 15,
),
);
}
if (show == null &&
deadFeed == null &&
snapshot.connectionState == ConnectionState.done) {
return SmartRefresher(
enablePullDown: true,
enablePullUp: false,
header: ClassicHeader(),
controller: _refreshController,
onRefresh: _onRefresh,
child: Container(
child: Center(
child: Text("An error occurred"),
),
),
);
} else {
show = show != null ? show : deadFeed;
return SmartRefresher(
enablePullDown: true,
enablePullUp: false,
header: ClassicHeader(),
controller: _refreshController,
onRefresh: _onRefresh,
child: StaggeredGridView.count(
controller: _controller,
crossAxisCount: 2,
children: List.generate(show.length, (int index) {
return show.elementAt(index).aspect == null ||
show.elementAt(index).aspect == "null"
? Container()
: double.parse(show.elementAt(index).aspect.toString()) <
1
? buildTile(
context, show.elementAt(index), 0.65, watch)
: buildTile(
context, show.elementAt(index), 0.35, watch);
}),
staggeredTiles: List.generate(
show.length,
(int index) {
return StaggeredTile.fit(1);
},
),
),
);
}
},
),
);
}
}

66
lib/Pages/Sub_Pages/homeSub/VideoList.dart

@ -1,66 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:provider/provider.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/Pages/Sub_Pages/Posts/ViewPost.dart';
import 'package:teso/providers/user_provider.dart';
class VideoList extends StatefulWidget {
final List<Post> postedAd;
VideoList({Key key, this.postedAd}) : super(key: key);
@override
_VideoListState createState() => _VideoListState();
}
class _VideoListState extends State<VideoList> {
@override
void initState() {
Provider.of<UserProvider>(context, listen: false)
.predownloadAds(widget.postedAd.map((e) => e.playbackID).toList());
super.initState();
}
report(Post post) {
Navigator.pop(context, post);
Navigator.pop(context, post);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.transparent,
leading: InkWell(
onTap: () => Navigator.pop(context),
child: Container(
height: 50,
width: 40,
margin: EdgeInsets.symmetric(
vertical: 30.0,
horizontal: 10,
),
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
),
),
extendBodyBehindAppBar: true,
body: PageView(
scrollDirection: Axis.vertical,
children: List<ViewPost>.generate(
widget.postedAd.length > 10 ? 10 : widget.postedAd.length,
(index) => new ViewPost(
play: true,
postedAd: widget.postedAd[index],
report: report,
)),
),
);
}
}

27
lib/Pages/Sub_Pages/userProfile3P.dart

@ -1,4 +1,3 @@
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:numeral/numeral.dart';
import 'package:page_transition/page_transition.dart';
@ -8,7 +7,6 @@ import 'package:teso/Classes/TesoUser.dart';
import 'package:flutter/material.dart';
import 'package:teso/Classes/customTesoButton.dart';
import 'package:teso/Pages/PageWidgets/Posts/posted.dart';
import 'package:teso/Pages/PageWidgets/Third Person Profile/header.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
@ -447,30 +445,7 @@ class _UserProfileThirdPersonState extends State<UserProfileThirdPerson>
snapshot.connectionState == ConnectionState.done) {
return buildEmpty3P(context);
} else {
return Container(
height: MediaQuery.of(context).size.height,
child: StaggeredGridView.count(
physics: scrolled
? NeverScrollableScrollPhysics()
: AlwaysScrollableScrollPhysics(),
controller: _controller,
crossAxisCount: 3,
children: List.generate(userProfile.posts.length, (int index) {
return buildPosted(
context,
userProfile.posts.elementAt(index),
0.325,
widget.user,
addFriends);
}),
staggeredTiles: List.generate(
userProfile.posts.length,
(int index) {
return StaggeredTile.fit(1);
},
),
),
);
return Container();
}
},
),

1
lib/Pages/codeQR.dart

@ -1,5 +1,4 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
// import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:flutter_qrcode_scanner/flutter_qrcode_scanner.dart';

189
lib/Pages/home.dart

@ -1,17 +1,14 @@
import 'package:flutter/material.dart';
import 'package:progress_indicators/progress_indicators.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:teso/Classes/Uploading.dart';
import 'package:teso/Pages/Sub_Pages/homeSub/MyCoupons.dart';
import 'package:teso/Pages/Sub_Pages/homeSub/HomeFeed.dart';
import 'package:teso/providers/pageAnimations.dart';
import 'package:teso/util/consts.dart';
import '../Classes/TesoShop.dart';
import 'Sub_Pages/CoinPurchase.dart';
import 'package:teso/providers/user_provider.dart';
import 'package:provider/provider.dart';
import 'Sub_Pages/homeSub/ProximityCoupons.dart';
import 'firsttimer.dart';
class Home extends StatefulWidget {
final Function showUploads;
@ -24,69 +21,86 @@ class Home extends StatefulWidget {
class _HomeState extends State<Home> with TickerProviderStateMixin {
Function showUploads;
_HomeState({this.showUploads});
TabController tabsController;
String title = "Home";
double titleSize = 45.0;
String mapstyle;
var _future;
static LatLng _initialPosition;
Set<Marker> markers = {};
List<TesoShop> shops;
GoogleMapController mapController;
static const double CAMERA_ZOOM = 13.499910354614258;
Location location = Location();
String routingMessage = "Finding shops....";
LocationData _location;
// ignore: unused_field
String _error;
@override
@override
void initState() {
super.initState();
tabsController = new TabController(length: 3, initialIndex: 1, vsync: this);
tabsController.addListener(() {
if (tabsController.index == 1) {
setState(() {
title = "Home";
titleSize = 45.0;
});
widget.toggle(true);
} else if (tabsController.index == 2) {
setState(() {
title = "Proximity Coupons";
titleSize = 30.0;
SharedPreferences.getInstance().then((prefs) async {
String currentTheme = prefs.getString("theme");
if (currentTheme == "dark") {
rootBundle.loadString('assets/styles/dark.txt').then((string) {
mapstyle = string;
});
widget.toggle(false);
} else {
setState(() {
title = "Coupons";
titleSize = 45.0;
rootBundle.loadString('assets/styles/light.txt').then((string) {
mapstyle = string;
});
widget.toggle(true);
}
});
SharedPreferences.getInstance().then((prefs) async {
bool first =
prefs.getBool("launched") != null ? prefs.getBool("launched") : false;
if (!first) {
int result = await Navigator.push(
context,
PageTransition(
type: PageTransitionType.fade,
child: FirstTimeIntro(),
));
prefs.setBool("launched", true);
tabsController.animateTo(result);
}
});
_future = _determinePosition(context);
location.onLocationChanged.listen((LocationData cLoc) {
_initialPosition = LatLng(cLoc.latitude, cLoc.longitude);
});
}
@override
void dispose() {
super.dispose();
tabsController.dispose();
}
Future<LatLng> _determinePosition(context) async {
setState(() {
_error = null;
});
try {
final LocationData _locationResult = await location.getLocation();
setState(() {
_location = _locationResult;
_initialPosition = LatLng(_location.latitude, _location.longitude);
});
// await getLocations();
return _initialPosition;
} on PlatformException catch (err) {
setState(() {
_error = err.code;
});
return _initialPosition;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: buildAppBar(context),
body: TabBarView(
controller: tabsController,
children: [
MyCoupons(),
HomeFeed(),
ProximityCoupons(),
],
),
//appBar: buildAppBar(context),
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return buildStaleMap(context);
} else {
return buildMap(context);
}
}),
);
}
@ -99,7 +113,6 @@ class _HomeState extends State<Home> with TickerProviderStateMixin {
automaticallyImplyLeading: false,
title: Consumer<UserProvider>(builder:
(BuildContext context, UserProvider value, Widget child) {
List<Uploading> provider = value.getPending();
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -116,23 +129,6 @@ class _HomeState extends State<Home> with TickerProviderStateMixin {
height: 30,
child: Row(
children: [
provider == null || provider.length == 0
? Container()
: GestureDetector(
onTap: () => showUploads(context),
child: Container(
height: 40,
width: 40,
margin: EdgeInsets.only(right: 15),
child: HeartbeatProgressIndicator(
child: Icon(
Icons.upload,
color: tesoBlue,
size: 18,
),
),
),
),
GestureDetector(
onTap: () => Navigator.push(
context,
@ -215,4 +211,71 @@ class _HomeState extends State<Home> with TickerProviderStateMixin {
),
preferredSize: Size.fromHeight(50.0));
}
Widget buildMap(BuildContext context) {
return GoogleMap(
// padding: EdgeInsets.only(
// top: 70.0,
// ),
zoomGesturesEnabled: true,
zoomControlsEnabled: false,
compassEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
// markers: markers,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: CAMERA_ZOOM,
//bearing: CAMERA_BEARING,
),
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(mapstyle);
mapController = controller;
},
onCameraMove: (position) {
setState(() {
try {
_initialPosition =
LatLng(position.target.latitude, position.target.longitude);
} catch (e) {
print(e);
}
});
},
// polylines: Set<Polyline>.of(polylines.values),
);
}
Widget buildStaleMap(BuildContext context) {
return GoogleMap(
// padding: EdgeInsets.only(
// top: 70.0,
// ),
zoomGesturesEnabled: true,
zoomControlsEnabled: false,
compassEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
markers: markers,
initialCameraPosition: CameraPosition(
target: LatLng(6.700071, -1.630783),
zoom: CAMERA_ZOOM,
//bearing: CAMERA_BEARING,
),
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(mapstyle);
mapController = controller;
},
onCameraMove: (position) {
setState(() {
try {
_initialPosition =
LatLng(position.target.latitude, position.target.longitude);
} catch (e) {
print(e);
}
});
},
);
}
}

1
lib/Services/services.dart

@ -1 +0,0 @@
export 'uservideo_controller_service.dart';

1
lib/Services/services2.dart

@ -1 +0,0 @@
export 'video_controller_service.dart';

67
lib/Services/uservideo_controller_service.dart

@ -1,67 +0,0 @@
import 'package:better_player/better_player.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
import 'package:teso/util/consts.dart';
abstract class VideoControllerService {
Future<BetterPlayerController> getControllerForVideo(FBPosts video);
}
class CachedVideoControllerService extends VideoControllerService {
// ignore: unused_field
final BaseCacheManager _cacheManager;
CachedVideoControllerService(this._cacheManager)
: assert(_cacheManager != null);
@override
Future<BetterPlayerController> getControllerForVideo(FBPosts video) async {
try {
BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
"https://stream.mux.com/${video.playbackID}.m3u8",
videoFormat: BetterPlayerVideoFormat.hls,
cacheConfiguration: BetterPlayerCacheConfiguration(
useCache: true,
),
);
return BetterPlayerController(
BetterPlayerConfiguration(
autoPlay: true,
aspectRatio: double.tryParse(video.aspect),
looping: true,
fit: double.parse(video.aspect) < 1
? BoxFit.fitHeight
: BoxFit.fitWidth,
showPlaceholderUntilPlay: true,
placeholder: Container(
child: Center(
child: CachedNetworkImage(
imageUrl: tesoPostThumb(video.playbackID),
imageBuilder: (context, imageProvider) => FadeInImage(
width: double.infinity,
fit: BoxFit.fill,
image: imageProvider,
placeholder: AssetImage("assets/images/blank.jpg"),
),
errorWidget: (context, url, error) =>
Image.asset("assets/images/blank.jpg"),
),
),
),
controlsConfiguration: BetterPlayerControlsConfiguration(
showControls: false,
),
autoDispose: true,
),
betterPlayerDataSource: betterPlayerDataSource,
);
} catch (e) {
// return BetterPlayerController.network(tesoStreaming + "pd/" + video.path);
return null;
}
}
}

66
lib/Services/video_controller_service.dart

@ -1,66 +0,0 @@
import 'package:better_player/better_player.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:teso/Classes/API%20Clasess/Post.dart';
import 'package:teso/util/consts.dart';
abstract class VideoControllerService {
Future<BetterPlayerController> getControllerForVideo(Post video);
}
class CachedVideoControllerService extends VideoControllerService {
// ignore: unused_field
final BaseCacheManager _cacheManager;
CachedVideoControllerService(this._cacheManager)
: assert(_cacheManager != null);
@override
Future<BetterPlayerController> getControllerForVideo(Post video) async {
try {
BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
"https://stream.mux.com/${video.playbackID}.m3u8",
videoFormat: BetterPlayerVideoFormat.hls,
cacheConfiguration: BetterPlayerCacheConfiguration(
useCache: true,
),
);
return BetterPlayerController(
BetterPlayerConfiguration(
autoPlay: true,
aspectRatio: double.tryParse(video.aspect),
looping: true,
fit: BoxFit.fill,
showPlaceholderUntilPlay: true,
placeholder: Container(
child: Center(
child: CachedNetworkImage(
imageUrl: tesoPostThumb(video.playbackID),
imageBuilder: (context, imageProvider) => FadeInImage(
width: double.infinity,
fit: BoxFit.fill,
image: imageProvider,
placeholder: AssetImage("assets/images/blank.jpg"),
),
errorWidget: (context, url, error) =>
Image.asset("assets/images/blank.jpg"),
),
),
),
controlsConfiguration: BetterPlayerControlsConfiguration(
showControls: false,
),
autoDispose: true,
),
betterPlayerDataSource: betterPlayerDataSource,
);
} catch (e) {
// return BetterPlayerController.network(tesoStreaming + "pd/" + video.path);
return null;
}
}
}

1
lib/blocs/blocs.dart

@ -1 +0,0 @@
export 'video_player/video_player.dart';

3
lib/blocs/video_player/uservideo_player.dart

@ -1,3 +0,0 @@
export 'video_player_bloc.dart';
export 'uservideo_player_event.dart';
export 'uservideo_player_state.dart';

28
lib/blocs/video_player/uservideo_player_bloc.dart

@ -1,28 +0,0 @@
import 'package:bloc/bloc.dart';
import 'package:teso/Services/services.dart';
import 'uservideo_player.dart';
class VideoPlayerBloc extends Bloc<VideoPlayerEvent, VideoPlayerState> {
final VideoControllerService _videoControllerService;
VideoPlayerBloc(this._videoControllerService)
: assert(_videoControllerService != null),
super(null);
VideoPlayerState get initialState => VideoPlayerStateInitial();
@override
Stream<VideoPlayerState> mapEventToState(VideoPlayerEvent event) async* {
if (event is VideoSelectedEvent) {
yield VideoPlayerStateLoading();
try {
final videoController =
await _videoControllerService.getControllerForVideo(event.video);
yield VideoPlayerStateLoaded(event.video, videoController);
} catch (e) {
yield VideoPlayerStateError(e.message ?? 'An unknown error occurred');
}
}
}
}

16
lib/blocs/video_player/uservideo_player_event.dart

@ -1,16 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:teso/Classes/Firebase/Posts.dart';
abstract class VideoPlayerEvent extends Equatable {
@override
List<Object> get props => const [];
}
class VideoSelectedEvent extends VideoPlayerEvent {
final FBPosts video;
VideoSelectedEvent(this.video) : assert(video != null);
@override
List<Object> get props => [video];
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save