Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/publishing issue #2356

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions easel/lib/easel_provider.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';

import 'package:dartz/dartz.dart';
import 'package:easel_flutter/main.dart';
import 'package:easel_flutter/models/denom.dart';
import 'package:easel_flutter/models/nft.dart';
Expand All @@ -12,10 +13,12 @@ import 'package:easel_flutter/models/upload_progress.dart';
import 'package:easel_flutter/repository/repository.dart';
import 'package:easel_flutter/screens/creator_hub/creator_hub_view_model.dart';
import 'package:easel_flutter/services/third_party_services/audio_player_helper.dart';
import 'package:easel_flutter/services/third_party_services/quick_node.dart';
import 'package:easel_flutter/services/third_party_services/video_player_helper.dart';
import 'package:easel_flutter/utils/constants.dart';
import 'package:easel_flutter/utils/enums.dart';
import 'package:easel_flutter/utils/extension_util.dart';
import 'package:easel_flutter/utils/failure/failure.dart';
import 'package:easel_flutter/utils/file_utils_helper.dart';
import 'package:easel_flutter/widgets/audio_widget.dart';
import 'package:easel_flutter/widgets/loading_with_progress.dart';
Expand Down Expand Up @@ -239,9 +242,7 @@ class EaselProvider extends ChangeNotifier {
royaltyController.text = royalties ?? "";
priceController.text = price ?? "";
noOfEditionController.text = edition ?? "";
_selectedDenom = denom != ""
? Denom.availableDenoms.firstWhere((element) => element.symbol == denom)
: Denom.availableDenoms.first;
_selectedDenom = denom != "" ? Denom.availableDenoms.firstWhere((element) => element.symbol == denom) : Denom.availableDenoms.first;
isFreeDrop = freeDrop!;
notifyListeners();
}
Expand Down Expand Up @@ -571,6 +572,9 @@ class EaselProvider extends ChangeNotifier {
final isCookBookCreated = await createCookbook();

if (isCookBookCreated) {
// this delay is added to wait the transaction is settle
// on the blockchain
await Future.delayed(const Duration(milliseconds: 800));
AhsanRns marked this conversation as resolved.
Show resolved Hide resolved
// get device cookbook id
_cookbookId = repository.getCookbookId();
notifyListeners();
Expand Down Expand Up @@ -680,8 +684,7 @@ class EaselProvider extends ChangeNotifier {
currentUsername = sdkResponse.data!.username;
stripeAccountExists = sdkResponse.data!.stripeExists;

supportedDenomList =
Denom.availableDenoms.where((Denom e) => sdkResponse.data!.supportedCoins.contains(e.symbol)).toList();
supportedDenomList = Denom.availableDenoms.where((Denom e) => sdkResponse.data!.supportedCoins.contains(e.symbol)).toList();

if (supportedDenomList.isNotEmpty && selectedDenom.symbol.isEmpty) {
_selectedDenom = supportedDenomList.first;
Expand Down Expand Up @@ -777,8 +780,7 @@ class EaselProvider extends ChangeNotifier {
}
}

bool isThumbnailPresent() =>
nftFormat.format == NFTTypes.audio || nftFormat.format == NFTTypes.video || nftFormat.format == NFTTypes.pdf;
bool isThumbnailPresent() => nftFormat.format == NFTTypes.audio || nftFormat.format == NFTTypes.video || nftFormat.format == NFTTypes.pdf;

Future<bool> saveNftLocally(UploadStep step) async {
final scaffoldMessengerOptionalState = navigatorKey.getState();
Expand Down Expand Up @@ -814,12 +816,26 @@ class EaselProvider extends ChangeNotifier {
uploadThumbnailResponse = uploadResponse.getOrElse(() => StorageResponseModel.initial());
}

final response = await repository.uploadFile(
file: _file!,
onUploadProgressCallback: (value) {
_uploadProgressController.sink.add(value);
},
);
final shouldUploadToQuickNode = QuickNode.listOfQuickNodeAllowedExtension().contains(fileExtension.toLowerCase());

Either<Failure, StorageResponseModel> response;

if (!shouldUploadToQuickNode) {
response = await repository.uploadFile(
file: _file!,
onUploadProgressCallback: (value) {
_uploadProgressController.sink.add(value);
},
);
} else {
response = await repository.uploadFileUsingQuickNode(
uploadIPFSInput: UploadIPFSInput(fileName: fileName, filePath: file!.path, contentType: QuickNode.getContentType(fileExtension)),
onUploadProgressCallback: (value) {
_uploadProgressController.sink.add(value);
},
);
}

if (response.isLeft()) {
loading.dismiss();
LocaleKeys.something_wrong_while_uploading.tr().show();
Expand Down
3 changes: 1 addition & 2 deletions easel/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool isTablet = false;

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp();
di.init();
final firebaseCrashlytics = GetIt.I.get<FirebaseCrashlytics>();
Expand Down Expand Up @@ -109,7 +109,6 @@ class MyApp extends StatelessWidget {
}
}


bool _getIsCurrentDeviceTablet() {
final MediaQueryData mediaQuery = MediaQueryData.fromView(PlatformDispatcher.instance.implicitView!);
return mediaQuery.size.shortestSide >= tabletMinWidth;
Expand Down
22 changes: 22 additions & 0 deletions easel/lib/models/storage_response_model.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:easel_flutter/services/third_party_services/quick_node.dart';

class StorageResponseModel {
bool? ok;
Value? value;
Expand All @@ -21,6 +23,26 @@ class StorageResponseModel {
factory StorageResponseModel.initial() {
return StorageResponseModel();
}

factory StorageResponseModel.fromQuickNode({required UploadIPFSOutput uploadIPFSOutput}) {
return StorageResponseModel(
ok: true,
value: Value(
cid: uploadIPFSOutput.pin?.cid,
created: uploadIPFSOutput.created,
size: int.parse(
uploadIPFSOutput.info?.size ?? '0',
),
pin: Pin(
cid: uploadIPFSOutput.pin?.cid,
created: uploadIPFSOutput.created,
size: int.parse(
uploadIPFSOutput.info?.size ?? '0',
),
status: uploadIPFSOutput.status,
)),
);
}
}

class Value {
Expand Down
20 changes: 20 additions & 0 deletions easel/lib/repository/repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:easel_flutter/services/datasources/local_datasource.dart';
import 'package:easel_flutter/services/datasources/remote_datasource.dart';
import 'package:easel_flutter/services/third_party_services/crashlytics_helper.dart';
import 'package:easel_flutter/services/third_party_services/network_info.dart';
import 'package:easel_flutter/services/third_party_services/quick_node.dart';
import 'package:easel_flutter/utils/extension_util.dart';
import 'package:easel_flutter/utils/failure/failure.dart';
import 'package:easel_flutter/utils/file_utils_helper.dart';
Expand Down Expand Up @@ -111,6 +112,11 @@ abstract class Repository {
/// Output : [ApiResponse] the ApiResponse which can contain [success] or [error] response
Future<Either<Failure, StorageResponseModel>> uploadFile({required File file, required OnUploadProgressCallback onUploadProgressCallback});

/// This method is used uploading provided file to the server using [QuickNode]
AhsanRns marked this conversation as resolved.
Show resolved Hide resolved
/// Input : [UploadIPFSInput] which needs to be uploaded
/// Output : [ApiResponse] the ApiResponse which can contain [success] or [error] response
Future<Either<Failure, StorageResponseModel>> uploadFileUsingQuickNode({required UploadIPFSInput uploadIPFSInput, required OnUploadProgressCallback onUploadProgressCallback});

/// This method will get the drafts List from the local database
/// Output: [List] returns that contains a number of [NFT]
Future<Either<Failure, List<NFT>>> getNfts();
Expand Down Expand Up @@ -317,7 +323,21 @@ class RepositoryImp implements Repository {

try {
final storageResponseModel = await remoteDataSource.uploadFile(file: file, uploadProgressCallback: onUploadProgressCallback);
return Right(storageResponseModel);
} on Exception catch (_) {
crashlyticsHelper.recordFatalError(error: _.toString());
return Left(CacheFailure(LocaleKeys.update_failed.tr()));
}
}

@override
Future<Either<Failure, StorageResponseModel>> uploadFileUsingQuickNode({required UploadIPFSInput uploadIPFSInput, required OnUploadProgressCallback onUploadProgressCallback}) async {
if (!await networkInfo.isConnected) {
return Left(NoInternetFailure(LocaleKeys.no_internet.tr()));
}

try {
final storageResponseModel = await remoteDataSource.uploadFileUsingQuickNode(uploadIPFSInput: uploadIPFSInput, onUploadProgressCallback: onUploadProgressCallback);
return Right(storageResponseModel);
} on Exception catch (exception) {
crashlyticsHelper.recordFatalError(error: exception.toString());
Expand Down
3 changes: 3 additions & 0 deletions easel/lib/screens/choose_format_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class _ChooseFormatScreenState extends State<ChooseFormatScreen> {
return;
}




AhsanRns marked this conversation as resolved.
Show resolved Hide resolved
if (!provider.nftFormat.extensions.contains(result.extension)) {
final fileName = result.fileName.replaceAll(".${result.extension}", "");
errorText.value = LocaleKeys.could_not_uploaded.tr(
Expand Down
40 changes: 9 additions & 31 deletions easel/lib/screens/publish_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,7 @@ class _PublishScreenState extends State<PublishScreen> {
body: Consumer<EaselProvider>(builder: (_, easelProvider, __) {
return Stack(
children: [
Positioned(
left: 0,
right: 0,
top: 0,
bottom: 0,
child: SizedBox(width: double.infinity, child: buildPreviewWidget(easelProvider))),
Positioned(left: 0, right: 0, top: 0, bottom: 0, child: SizedBox(width: double.infinity, child: buildPreviewWidget(easelProvider))),
Positioned(
left: 10.w,
top: 30.h,
Expand Down Expand Up @@ -187,10 +182,7 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
collapseStatus: viewModel.collapsed,
onCollapsed: (context) => DecoratedBox(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [EaselAppTheme.kTransparent, EaselAppTheme.kBlack]),
gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [EaselAppTheme.kTransparent, EaselAppTheme.kBlack]),
),
child: Padding(
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 8.h, bottom: 16.h),
Expand Down Expand Up @@ -236,11 +228,7 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
builder: (_, value, __) {
switch (value) {
case ButtonState.loading:
return SizedBox(
height: 20.h,
width: 15.h,
child: CircularProgressIndicator(
strokeWidth: 2.w, color: EaselAppTheme.kWhite));
return SizedBox(height: 20.h, width: 15.h, child: CircularProgressIndicator(strokeWidth: 2.w, color: EaselAppTheme.kWhite));
case ButtonState.paused:
return InkWell(
onTap: () {
Expand Down Expand Up @@ -282,8 +270,7 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
bufferedBarColor: EaselAppTheme.kLightGrey,
buffered: value.buffered,
total: value.total,
timeLabelTextStyle: TextStyle(
color: EaselAppTheme.kWhite, fontWeight: FontWeight.w800, fontSize: 9.sp),
timeLabelTextStyle: TextStyle(color: EaselAppTheme.kWhite, fontWeight: FontWeight.w800, fontSize: 9.sp),
thumbRadius: 10.h,
timeLabelPadding: 3.h,
onSeek: (position) {
Expand Down Expand Up @@ -316,9 +303,7 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_title(
nft: widget.nft,
owner: widget.nft.type == NftType.TYPE_RECIPE.name ? "you".tr() : widget.nft.creator),
_title(nft: widget.nft, owner: widget.nft.type == NftType.TYPE_RECIPE.name ? "you".tr() : widget.nft.creator),
SizedBox(
height: 30.h,
),
Expand Down Expand Up @@ -387,16 +372,14 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
subtitle: "${widget.nft.tradePercentage}%",
),
SizedBox(height: 5.h),
buildRow(
title: LocaleKeys.content_identifier.tr(), subtitle: widget.nft.cid, canCopy: true),
buildRow(title: LocaleKeys.content_identifier.tr(), subtitle: widget.nft.cid, canCopy: true),
SizedBox(height: 5.h),
CidOrIpfs(
viewCid: (context) {
return const SizedBox.shrink();
},
viewIpfs: (context) {
return buildRow(
title: LocaleKeys.asset_uri.tr(), subtitle: LocaleKeys.view.tr(), viewIPFS: true);
return buildRow(title: LocaleKeys.asset_uri.tr(), subtitle: LocaleKeys.view.tr(), viewIPFS: true);
},
type: widget.nft.assetType,
),
Expand Down Expand Up @@ -522,10 +505,7 @@ class _OwnerBottomDrawerState extends State<OwnerBottomDrawer> {
builder: (_, value, __) {
switch (value) {
case ButtonState.loading:
return SizedBox(
height: 22.h,
width: 22.h,
child: CircularProgressIndicator(strokeWidth: 2.w, color: EaselAppTheme.kWhite));
return SizedBox(height: 22.h, width: 22.h, child: CircularProgressIndicator(strokeWidth: 2.w, color: EaselAppTheme.kWhite));
case ButtonState.paused:
return InkWell(
onTap: () {
Expand Down Expand Up @@ -751,9 +731,7 @@ class BuildPublishBottomSheet extends StatelessWidget {
final WidgetBuilder onOpened;
final bool collapseStatus;

const BuildPublishBottomSheet(
{Key? key, required this.onCollapsed, required this.onOpened, required this.collapseStatus})
: super(key: key);
const BuildPublishBottomSheet({Key? key, required this.onCollapsed, required this.onOpened, required this.collapseStatus}) : super(key: key);

@override
Widget build(BuildContext context) {
Expand Down
22 changes: 19 additions & 3 deletions easel/lib/services/datasources/remote_datasource.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:easel_flutter/easel_provider.dart';
import 'package:easel_flutter/models/storage_response_model.dart';
import 'package:easel_flutter/models/upload_progress.dart';
import 'package:easel_flutter/services/third_party_services/analytics_helper.dart';
import 'package:easel_flutter/services/third_party_services/quick_node.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:pylons_sdk/low_level.dart';

Expand All @@ -21,19 +22,34 @@ abstract class RemoteDataSource {
/// Output : [Future<List<Recipe>>] which will be a Future list of Recipes against the given [cookbookID]
Future<List<Recipe>> getRecipesByCookbookID(String cookBookID);



/// This method is used to log user journey in the easel app.
/// Input: [screenName] the screen name in the easel.
/// Output: [bool] tells whether the user journey is recorded or not
Future<bool> logUserJourney({required String screenName});

/// This method is used uploading provided file to the server using [QuickNode]
/// Input : [UploadIPFSInput] which needs to be uploaded
/// Output : [Future<ApiResponse<StorageResponseModel>>] the ApiResponse which can contain [success] or [error] response
Future<StorageResponseModel> uploadFileUsingQuickNode({required UploadIPFSInput uploadIPFSInput, required OnUploadProgressCallback onUploadProgressCallback});
}

class RemoteDataSourceImpl implements RemoteDataSource {
final Dio httpClient;
final AnalyticsHelper analyticsHelper;
final QuickNode quickNode;

RemoteDataSourceImpl({required this.httpClient, required this.analyticsHelper});
RemoteDataSourceImpl({
required this.httpClient,
required this.analyticsHelper,
required this.quickNode,
});

@override
Future<StorageResponseModel> uploadFileUsingQuickNode({required UploadIPFSInput uploadIPFSInput, required OnUploadProgressCallback onUploadProgressCallback}) async {

final response = await quickNode.uploadNewObjectToIPFS(uploadIPFSInput: uploadIPFSInput, onUploadProgressCallback: onUploadProgressCallback);
return response;
}
AhsanRns marked this conversation as resolved.
Show resolved Hide resolved

@override
Future<StorageResponseModel> uploadFile({required OnUploadProgressCallback uploadProgressCallback, required File file}) async {
Expand Down
Loading
Loading