Merge pull request 'main' (#34) from eatvio/eatvio_app:main into main

Reviewed-on: #34
This commit is contained in:
mso7nueh
2025-05-12 12:51:19 +00:00
24 changed files with 283 additions and 223 deletions

View File

@@ -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

3
ios/Gemfile Normal file
View File

@@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "fastlane"

View File

@@ -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)",

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<string>9</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

View File

@@ -0,0 +1,2 @@
FASTLANE_USER=eatvio2023@icloud.com
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=iqsm-pfxm-bpmg-nkry

8
ios/fastlane/Appfile Normal file
View File

@@ -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

26
ios/fastlane/Fastfile Normal file
View File

@@ -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

32
ios/fastlane/README.md Normal file
View File

@@ -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).

28
ios/fastlane/report.xml Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="fastlane.lanes">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000206">
</testcase>
<testcase classname="fastlane.lanes" name="1: increment_build_number" time="0.195115">
</testcase>
<testcase classname="fastlane.lanes" name="2: build_app" time="116.686863">
</testcase>
<testcase classname="fastlane.lanes" name="3: upload_to_testflight" time="338.642203">
</testcase>
</testsuite>
</testsuites>

View File

@@ -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<MyDietsCubit>().unpublishDiet(id!);
if (!context.mounted) return;
context.read<FeedCubit>().loadFeedBlogPostList();
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
showSuccessToast('Диета перенесена в архив, обновите ленту');
} else if (complainedContentType == ComplainedContent.plan) {
final result = await sl<MyPlansCubit>().unpublish(slug!);
if (!context.mounted) return;
context.read<FeedCubit>().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<BlogPostCreateCubit>().deleteBlogPost(id!);
if (!context.mounted) return;
context.read<FeedCubit>().loadFeedBlogPostList();
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
showSuccessToast('Пост удален, обновите ленту');
} else if (complainedContentType == ComplainedContent.recipe) {
final result = await sl<RecipesCubit>().deleteRecipe(slug!);
if (!context.mounted) return;
context.read<FeedCubit>().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<DietsCubit>().deleteDiet(id!);
if (!context.mounted) return;
context.read<FeedCubit>().loadFeedBlogPostList();
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
showSuccessToast('Диета удалена, обновите ленту');
} else if (complainedContentType == ComplainedContent.plan) {
final result = await sl<MyPlansCubit>().deletePlan(slug!);
if (!context.mounted) return;
context.read<FeedCubit>().loadFeedBlogPostList();
if (!result) {
showErrorDialog(context, title: S.current.could_not_delete_blog_post);
return;
}
showSuccessToast('План удален, обновите ленту');
}
});
} else {

View File

@@ -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<DietPreviewScreen> {
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(

View File

@@ -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<AboutDietScreen> {
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<AboutDietScreen> {
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(),

View File

@@ -65,6 +65,14 @@ class DietRepository {
}
}
Future<void> 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);

View File

@@ -39,4 +39,9 @@ abstract class DietService {
Future<void> cancelDiet({
@Path() required int id,
});
@DELETE('/api/diets/delete/{id}')
Future<void> deleteDiet({
@Path() required int id,
});
}

View File

@@ -29,6 +29,7 @@ class DietsCubit extends Cubit<DietsState> {
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<DietsState> {
},
);
}
Future<bool> deleteDiet(int dietId) async {
try {
await dietsRepository.deleteDiet(dietId);
return true;
} catch (e) {
return false;
}
}
}

View File

@@ -49,7 +49,7 @@ class RecipesCubit extends Cubit<RecipesState> {
tags: _selectedTags.toList(),
query: query,
);
final recipesTags = (await recipeRepository.getRecipesTags());
emit(
state.copyWith(
@@ -129,7 +129,7 @@ class RecipesCubit extends Cubit<RecipesState> {
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<RecipesState> {
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<RecipesState> {
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<RecipesState> {
),
);
}
Future<bool> deleteRecipe(String slug) async {
try {
await aboutRecipeRepository.deleteRecipe(slug);
return true;
} catch (e) {
return false;
}
}
}

View File

@@ -204,4 +204,13 @@ class MyPlansCubit extends Cubit<MyPlansState> {
return false;
}
}
Future<bool> unpublish(String slug) async {
try {
await myPlansRepository.unpublish(slug);
return true;
} catch (e) {
return false;
}
}
}

View File

@@ -35,5 +35,8 @@ class MyPlansRepository {
rethrow;
}
}
Future<void> unpublish(String slug) async {
return await myPlansService.unpublish(slug: slug);
}
}

View File

@@ -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<PlanPaginationModel> getPlans({
@@ -24,5 +23,8 @@ abstract class MyPlansService {
@Path() required String slug,
});
}
@POST('/api/plans/draft/{slug}')
Future<void> unpublish({
@Path() required String slug,
});
}

View File

@@ -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<AboutPlanScreen> {
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<AboutPlanCubit>().getPlan(widget.plan.slug)),
@@ -380,31 +360,13 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
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(

View File

@@ -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<AboutRecipeScreen> {
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<AboutRecipeCubit>().getRecipe(widget.recipe.slug, index: widget.index)),
@@ -432,23 +420,13 @@ class _AboutRecipeScreenState extends State<AboutRecipeScreen> {
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(),

View File

@@ -47,6 +47,14 @@ class AboutRecipeRepository {
}
}
Future<void> 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);

View File

@@ -25,4 +25,9 @@ abstract class AboutRecipeService {
@GET('/api/recipes/show/{id}')
Future<Recipe> getRecipe(@Path() String id);
@DELETE('/api/recipes/delete/{slug}')
Future<void> deleteRecipe({
@Path() required String slug,
});
}

View File

@@ -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: