diff --git a/.gitea/workflows/test-flight-cd.yaml b/.gitea/workflows/test-flight-cd.yaml index 1bb78c94..5d7e74ae 100644 --- a/.gitea/workflows/test-flight-cd.yaml +++ b/.gitea/workflows/test-flight-cd.yaml @@ -10,49 +10,21 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - - name: Remove cache - run: rm -rf /Users/gitea_runner_ci/Library/Developer/Xcode/DerivedData/* - - - name: Download provisioning - uses: mso7nueh/apple-provisioning-profiles-downloader@v1.0.8 - with: - profile-type: IOS_APP_STORE - bundle-id: com.eatvioapp.app - issuer-id: ${{ vars.APPSTORE_ISSUER_ID }} - api-key-id: ${{ vars.APPSTORE_KEY_ID }} - api-private-key: ${{ vars.APPSTORE_PRIVATE_KEY }} - - - name: Unlock keychain - run: | - security unlock-keychain -p "EeChahboo9Ei" login.keychain - security set-key-partition-list -S apple-tool:,apple: -s -k "EeChahboo9Ei" login.keychain - - - name: Ensure private key access - run: | - security set-key-partition-list -S apple-tool:,apple: -s -k "EeChahboo9Ei" ~/Library/Keychains/login.keychain-db - - - name: List identities in keychain - run: | - security list-keychains - security find-identity -v -p codesigning login.keychain - - - name: Set keychain default - run: | - security default-keychain -s login.keychain - - - name: Build with Flutter + + - name: Flutter build run: | flutter clean flutter pub get flutter pub upgrade flutter pub run build_runner build --delete-conflicting-outputs - flutter build ipa --export-options-plist=Support/ExportOptions.plist --release - - - name: Upload to TestFlight - uses: mso7nueh/upload-testflight-build@master - with: - app-path: ./build/ios/ipa/eatvio_app.ipa - issuer-id: ${{ vars.APPSTORE_ISSUER_ID }} - api-key-id: ${{ vars.APPSTORE_KEY_ID }} - api-private-key: ${{ vars.APPSTORE_PRIVATE_KEY }} + cd ios + pod update + fastlane beta + env: + LANG: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + MATCH_PASSWORD: EeChahboo9Ei + MATCH_GIT_URL: http://gitea.office.local:3000/mso7nueh/fastlane + FASTLANE_USER: eatvio2023@icloud.com + FASTLANE_PASSWORD: EeChahboo9Ei + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: iqsm-pfxm-bpmg-nkry \ No newline at end of file diff --git a/ios/Gemfile b/ios/Gemfile new file mode 100644 index 00000000..7a118b49 --- /dev/null +++ b/ios/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index c2ccb23a..12490b49 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -388,8 +388,8 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; - DEVELOPMENT_TEAM = ""; + CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -538,8 +538,8 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; - DEVELOPMENT_TEAM = ""; + CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -576,8 +576,8 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; - DEVELOPMENT_TEAM = ""; + CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index b6470ce4..eada9fab 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - $(FLUTTER_BUILD_NUMBER) + 9 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/fastlane/.env.default b/ios/fastlane/.env.default new file mode 100644 index 00000000..49b144e2 --- /dev/null +++ b/ios/fastlane/.env.default @@ -0,0 +1,2 @@ +FASTLANE_USER=eatvio2023@icloud.com +FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=iqsm-pfxm-bpmg-nkry \ No newline at end of file diff --git a/ios/fastlane/Appfile b/ios/fastlane/Appfile new file mode 100644 index 00000000..b36199d4 --- /dev/null +++ b/ios/fastlane/Appfile @@ -0,0 +1,8 @@ +app_identifier("com.eatvioapp.app") # The bundle identifier of your app +apple_id("eatvio2023@icloud.com") # Your Apple Developer Portal username + +itc_team_id("126794592") # App Store Connect Team ID +team_id("VL68C36HYS") # Developer Portal Team ID + +# For more information about the Appfile, see: +# https://docs.fastlane.tools/advanced/#appfile diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile new file mode 100644 index 00000000..4c53abd3 --- /dev/null +++ b/ios/fastlane/Fastfile @@ -0,0 +1,26 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:ios) + +platform :ios do + desc "Push a new beta build to TestFlight" + lane :beta do + match(type: "appstore") + increment_build_number(xcodeproj: "Runner.xcodeproj") + build_app(workspace: "Runner.xcworkspace", scheme: "Runner", export_method: "app-store") + upload_to_testflight + end +end diff --git a/ios/fastlane/README.md b/ios/fastlane/README.md new file mode 100644 index 00000000..891747df --- /dev/null +++ b/ios/fastlane/README.md @@ -0,0 +1,32 @@ +fastlane documentation +---- + +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +```sh +xcode-select --install +``` + +For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) + +# Available Actions + +## iOS + +### ios beta + +```sh +[bundle exec] fastlane ios beta +``` + +Push a new beta build to TestFlight + +---- + +This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. + +More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). + +The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml new file mode 100644 index 00000000..c86e2b65 --- /dev/null +++ b/ios/fastlane/report.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/core/widgets/custom_popup.dart b/lib/core/widgets/custom_popup.dart index 711995f2..a4167f11 100644 --- a/lib/core/widgets/custom_popup.dart +++ b/lib/core/widgets/custom_popup.dart @@ -7,7 +7,11 @@ import 'package:eatvio_app/core/widgets/show_error_dialog.dart'; import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart'; import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart'; import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart'; +import 'package:eatvio_app/features/my_diets/presentation/cubit/my_diets_cubit.dart'; +import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -96,23 +100,65 @@ class CustomPopup extends StatelessWidget { } }); if (complainedContentType == ComplainedContent.plan || complainedContentType == ComplainedContent.diet) { - addItem('assets/icons/remove_from_public.svg', 'Снять с публикации', () { - showInfoToast('В разработке'); - return; + addItem('assets/icons/remove_from_public.svg', 'Снять с публикации', () async { + if (complainedContentType == ComplainedContent.diet) { + final result = await sl().unpublishDiet(id!); + if (!context.mounted) return; + context.read().loadFeedBlogPostList(); + if (!result) { + showErrorDialog(context, title: S.current.could_not_delete_blog_post); + return; + } + showSuccessToast('Диета перенесена в архив, обновите ленту'); + } else if (complainedContentType == ComplainedContent.plan) { + final result = await sl().unpublish(slug!); + if (!context.mounted) return; + context.read().loadFeedBlogPostList(); + if (!result) { + showErrorDialog(context, title: S.current.could_not_delete_blog_post); + return; + } + showSuccessToast('План перенесен в архив, обновите ленту'); + } }); } addItem('assets/icons/red_trash.svg', 'Удалить', () async { if (complainedContentType == ComplainedContent.posts) { final result = await sl().deleteBlogPost(id!); if (!context.mounted) return; + context.read().loadFeedBlogPostList(); if (!result) { showErrorDialog(context, title: S.current.could_not_delete_blog_post); return; } + showSuccessToast('Пост удален, обновите ленту'); + } else if (complainedContentType == ComplainedContent.recipe) { + final result = await sl().deleteRecipe(slug!); + if (!context.mounted) return; context.read().loadFeedBlogPostList(); - } else { - showInfoToast('В разработке'); - return; + if (!result) { + showErrorDialog(context, title: S.current.could_not_delete_blog_post); + return; + } + showSuccessToast('Рецепт удален, обновите ленту'); + } else if (complainedContentType == ComplainedContent.diet) { + final result = await sl().deleteDiet(id!); + if (!context.mounted) return; + context.read().loadFeedBlogPostList(); + if (!result) { + showErrorDialog(context, title: S.current.could_not_delete_blog_post); + return; + } + showSuccessToast('Диета удалена, обновите ленту'); + } else if (complainedContentType == ComplainedContent.plan) { + final result = await sl().deletePlan(slug!); + if (!context.mounted) return; + context.read().loadFeedBlogPostList(); + if (!result) { + showErrorDialog(context, title: S.current.could_not_delete_blog_post); + return; + } + showSuccessToast('План удален, обновите ленту'); } }); } else { diff --git a/lib/features/create_diet/presentation/diet_preview_screen.dart b/lib/features/create_diet/presentation/diet_preview_screen.dart index 759a9ad3..884c283d 100644 --- a/lib/features/create_diet/presentation/diet_preview_screen.dart +++ b/lib/features/create_diet/presentation/diet_preview_screen.dart @@ -1,24 +1,24 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:eatvio_app/core/enums/complained_content.dart'; import 'package:eatvio_app/core/enums/product_type.dart'; import 'package:eatvio_app/core/utils/localization_utils.dart'; import 'package:eatvio_app/core/utils/string_extentions.dart'; import 'package:eatvio_app/core/widgets/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; +import 'package:eatvio_app/core/widgets/custom_popup.dart'; import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart'; import 'package:eatvio_app/core/widgets/cpfc_container.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; class DietPreviewScreen extends StatefulWidget { @@ -190,30 +190,12 @@ class _DietPreviewScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - disableActions: true, - path: 'diet/${widget.diet.id}', - ), - anchor: const Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ), - ), + CustomPopup( + isAuthor: widget.diet.author.authorIsMe, + path: 'diet/${widget.diet.id}', + complainedContentType: ComplainedContent.diet, ), + const SizedBox(width: 16), ], ), body: SingleChildScrollView( diff --git a/lib/features/diets/presentation/pages/about_diet_screen.dart b/lib/features/diets/presentation/pages/about_diet_screen.dart index d4a07038..8a21395a 100644 --- a/lib/features/diets/presentation/pages/about_diet_screen.dart +++ b/lib/features/diets/presentation/pages/about_diet_screen.dart @@ -19,7 +19,6 @@ import 'package:eatvio_app/features/diets/presentation/widgets/cancel_diet_botto import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/start_diet_bottom_sheet.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart'; @@ -32,7 +31,6 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; class AboutDietScreen extends StatefulWidget { @@ -498,31 +496,13 @@ class _AboutDietScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - path: 'diet/${widget.diet.id}', - complainedContentType: ComplainedContent.diet, - id: widget.diet.id, - ), - anchor: const Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ), - ), + CustomPopup( + isAuthor: widget.diet.author.authorIsMe, + path: 'diet/${widget.diet.id}', + complainedContentType: ComplainedContent.diet, + id: widget.diet.id, ), + const SizedBox(width: 16), ], ), body: DataErrorWidget( @@ -542,31 +522,13 @@ class _AboutDietScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - path: 'diet/${widget.diet.id}', - complainedContentType: ComplainedContent.diet, - id: widget.diet.id, - ), - anchor: const Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ), - ), + CustomPopup( + isAuthor: widget.diet.author.authorIsMe, + path: 'diet/${widget.diet.id}', + complainedContentType: ComplainedContent.diet, + id: widget.diet.id, ), + const SizedBox(width: 16), ], ), body: const Loader(), diff --git a/lib/features/diets/repositories/diet_repository.dart b/lib/features/diets/repositories/diet_repository.dart index cefc0c26..a3bbbbb3 100644 --- a/lib/features/diets/repositories/diet_repository.dart +++ b/lib/features/diets/repositories/diet_repository.dart @@ -65,6 +65,14 @@ class DietRepository { } } + Future deleteDiet(int id) async { + try { + return await dietsService.deleteDiet(id: id); + } catch (e) { + rethrow; + } + } + void emitLikesStateToFeed(LikesState state) => _dietLikeStateStreamController.add(state); void emitFavoriteStateToFeed(FavoriteState state) => _dietFavoriteStateStreamController.add(state); void emitCommentsStateToFeed(CommentsState state) => _dietCommentsStateStreamController.add(state); diff --git a/lib/features/diets/services/diet_service.dart b/lib/features/diets/services/diet_service.dart index c93e3296..59c2c977 100644 --- a/lib/features/diets/services/diet_service.dart +++ b/lib/features/diets/services/diet_service.dart @@ -39,4 +39,9 @@ abstract class DietService { Future cancelDiet({ @Path() required int id, }); + + @DELETE('/api/diets/delete/{id}') + Future deleteDiet({ + @Path() required int id, + }); } diff --git a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart index 23c7ae37..3f1ea0b0 100644 --- a/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart +++ b/lib/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart @@ -29,6 +29,7 @@ class DietsCubit extends Cubit { late final StreamSubscription likesStateSubscription; late final StreamSubscription favoriteStateSubscription; late final StreamSubscription commentsStateSubscription; + DietsCubit({ required this.feedRepository, required this.dietsRepository, @@ -342,4 +343,13 @@ class DietsCubit extends Cubit { }, ); } + + Future deleteDiet(int dietId) async { + try { + await dietsRepository.deleteDiet(dietId); + return true; + } catch (e) { + return false; + } + } } diff --git a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart index 18c7ebb8..866d4abb 100644 --- a/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart +++ b/lib/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart @@ -49,7 +49,7 @@ class RecipesCubit extends Cubit { tags: _selectedTags.toList(), query: query, ); - + final recipesTags = (await recipeRepository.getRecipesTags()); emit( state.copyWith( @@ -129,7 +129,7 @@ class RecipesCubit extends Cubit { EasyDebounce.debounce( 'add_or_remove_plan_from_favorite', const Duration(milliseconds: 200), - () async { + () async { try { await aboutRecipeRepository.addToFavorite(slug); } catch (e) { @@ -169,7 +169,7 @@ class RecipesCubit extends Cubit { EasyDebounce.debounce( 'add_or_remove_plan_from_favorite', const Duration(milliseconds: 200), - () async { + () async { try { await aboutRecipeRepository.removeFromFavorite(slug); } catch (e) { @@ -225,7 +225,7 @@ class RecipesCubit extends Cubit { EasyDebounce.debounce( 'like_plan', const Duration(milliseconds: 200), - () async { + () async { try { await aboutRecipeRepository.likeRecipe(slug); } catch (e) { @@ -300,4 +300,13 @@ class RecipesCubit extends Cubit { ), ); } + + Future deleteRecipe(String slug) async { + try { + await aboutRecipeRepository.deleteRecipe(slug); + return true; + } catch (e) { + return false; + } + } } diff --git a/lib/features/my_plans/presentation/cubit/my_plans_cubit.dart b/lib/features/my_plans/presentation/cubit/my_plans_cubit.dart index 6c14003f..33462563 100644 --- a/lib/features/my_plans/presentation/cubit/my_plans_cubit.dart +++ b/lib/features/my_plans/presentation/cubit/my_plans_cubit.dart @@ -204,4 +204,13 @@ class MyPlansCubit extends Cubit { return false; } } + + Future unpublish(String slug) async { + try { + await myPlansRepository.unpublish(slug); + return true; + } catch (e) { + return false; + } + } } diff --git a/lib/features/my_plans/repositories/my_diets_repository.dart b/lib/features/my_plans/repositories/my_diets_repository.dart index a28c88cd..1ee9afb1 100644 --- a/lib/features/my_plans/repositories/my_diets_repository.dart +++ b/lib/features/my_plans/repositories/my_diets_repository.dart @@ -35,5 +35,8 @@ class MyPlansRepository { rethrow; } } - + + Future unpublish(String slug) async { + return await myPlansService.unpublish(slug: slug); + } } diff --git a/lib/features/my_plans/services/my_plans_service.dart b/lib/features/my_plans/services/my_plans_service.dart index ee81e55e..9c5cbf0c 100644 --- a/lib/features/my_plans/services/my_plans_service.dart +++ b/lib/features/my_plans/services/my_plans_service.dart @@ -6,8 +6,7 @@ part 'my_plans_service.g.dart'; @RestApi() abstract class MyPlansService { - - factory MyPlansService(Dio dio, {String baseUrl}) = _MyPlansService; + factory MyPlansService(Dio dio, {String baseUrl}) = _MyPlansService; @GET('/api/plans/index') Future getPlans({ @@ -24,5 +23,8 @@ abstract class MyPlansService { @Path() required String slug, }); - -} \ No newline at end of file + @POST('/api/plans/draft/{slug}') + Future unpublish({ + @Path() required String slug, + }); +} diff --git a/lib/features/plans/presentation/pages/about_plan_screen.dart b/lib/features/plans/presentation/pages/about_plan_screen.dart index 3d35fc51..72cb71bd 100644 --- a/lib/features/plans/presentation/pages/about_plan_screen.dart +++ b/lib/features/plans/presentation/pages/about_plan_screen.dart @@ -15,7 +15,6 @@ import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart' import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_state.dart'; @@ -30,7 +29,6 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; @@ -143,31 +141,13 @@ class _AboutPlanScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - complainedContentType: ComplainedContent.plan, - path: 'plan/${widget.plan.id}', - slug: widget.plan.slug, - ), - anchor: const Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ), - ), + CustomPopup( + isAuthor: widget.plan.author.authorIsMe, + path: 'plan/${widget.plan.id}', + complainedContentType: ComplainedContent.plan, + slug: widget.plan.slug, ), + const SizedBox(width: 16), ], ), body: DataErrorWidget(onReload: () => context.read().getPlan(widget.plan.slug)), @@ -380,31 +360,13 @@ class _AboutPlanScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - complainedContentType: ComplainedContent.plan, - path: 'plan/${widget.plan.id}', - slug: widget.plan.slug, - ), - anchor: const Aligned( - shiftToWithinBound: AxisFlag(x: true, y: true), - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset( - 'assets/icons/more_button.svg', - width: 20, - height: 20, - ), - ), + CustomPopup( + isAuthor: widget.plan.author.authorIsMe, + path: 'plan/${widget.plan.id}', + complainedContentType: ComplainedContent.plan, + slug: widget.plan.slug, ), + const SizedBox(width: 16), ], ), body: SingleChildScrollView( diff --git a/lib/features/recipe/presentation/about_recipe_screen.dart b/lib/features/recipe/presentation/about_recipe_screen.dart index cc65a0c2..2436ba0b 100644 --- a/lib/features/recipe/presentation/about_recipe_screen.dart +++ b/lib/features/recipe/presentation/about_recipe_screen.dart @@ -16,7 +16,6 @@ import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart' import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; -import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/feed/models/recipes_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_state.dart'; @@ -32,7 +31,6 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -398,23 +396,13 @@ class _AboutRecipeScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - complainedContentType: ComplainedContent.recipe, - path: 'recipe/${widget.recipe.slug}', - slug: widget.recipe.slug, - ), - anchor: const Aligned(shiftToWithinBound: AxisFlag(x: true, y: true), follower: Alignment.topRight, target: Alignment.bottomRight), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset('assets/icons/more_button.svg', width: 20, height: 20), - ), + CustomPopup( + isAuthor: widget.recipe.author.authorIsMe, + path: 'recipe/${widget.recipe.slug}', + complainedContentType: ComplainedContent.recipe, + slug: widget.recipe.slug, ), + const SizedBox(width: 16), ], ), body: DataErrorWidget(onReload: () => context.read().getRecipe(widget.recipe.slug, index: widget.index)), @@ -432,23 +420,13 @@ class _AboutRecipeScreenState extends State { style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ - PortalTarget( - visible: isMoreOptionsVisible, - portalFollower: MoreOptions( - complainedContentType: ComplainedContent.recipe, - path: 'recipe/${widget.recipe.slug}', - slug: widget.recipe.slug, - ), - anchor: const Aligned(shiftToWithinBound: AxisFlag(x: true, y: true), follower: Alignment.topRight, target: Alignment.bottomRight), - child: IconButton( - onPressed: () { - setState(() { - isMoreOptionsVisible = !isMoreOptionsVisible; - }); - }, - icon: SvgPicture.asset('assets/icons/more_button.svg', width: 20, height: 20), - ), + CustomPopup( + isAuthor: widget.recipe.author.authorIsMe, + path: 'recipe/${widget.recipe.slug}', + complainedContentType: ComplainedContent.recipe, + slug: widget.recipe.slug, ), + const SizedBox(width: 16), ], ), body: const Loader(), diff --git a/lib/features/recipe/repositories/about_recipe_repository.dart b/lib/features/recipe/repositories/about_recipe_repository.dart index a9178a65..df433f5e 100644 --- a/lib/features/recipe/repositories/about_recipe_repository.dart +++ b/lib/features/recipe/repositories/about_recipe_repository.dart @@ -47,6 +47,14 @@ class AboutRecipeRepository { } } + Future deleteRecipe(String slug) async { + try { + await recipeService.deleteRecipe(slug: slug); + } catch (e) { + rethrow; + } + } + void emitLikesStateToFeed(LikesState state) => _recipeLikeStateStreamController.add(state); void emitFavoriteStateToFeed(FavoriteState state) => _recipeFavoriteStateStreamController.add(state); void emitCommentsStateToFeed(CommentsState state) => _recipeCommentsStateStreamController.add(state); diff --git a/lib/features/recipe/services/about_recipe_service.dart b/lib/features/recipe/services/about_recipe_service.dart index b326f970..21170ed4 100644 --- a/lib/features/recipe/services/about_recipe_service.dart +++ b/lib/features/recipe/services/about_recipe_service.dart @@ -25,4 +25,9 @@ abstract class AboutRecipeService { @GET('/api/recipes/show/{id}') Future getRecipe(@Path() String id); + + @DELETE('/api/recipes/delete/{slug}') + Future deleteRecipe({ + @Path() required String slug, + }); } diff --git a/pubspec.yaml b/pubspec.yaml index 46ddf5d1..1b99db27 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: eatvio_app description: A new Flutter project. -version: 1.0.51+6 +version: 1.1.1+1 publish_to: 'none' environment: