Merge pull request 'build 26 + 1.1.3+33' (#496) from main into test-flight

Reviewed-on: eatvio/eatvio_app#496
This commit is contained in:
mso7nueh
2025-06-06 08:33:37 +00:00
13 changed files with 78 additions and 25 deletions

View File

@@ -388,7 +388,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 25;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -538,7 +538,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 25;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -576,7 +576,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 25;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>24</string>
<string>25</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

View File

@@ -364,9 +364,12 @@ class AppRouter {
path: UserDiaryScreen.path,
name: UserDiaryScreen.name,
builder: (context, state) {
final diaryId = state.extra as int;
final data = state.extra as Map<String, int>;
final diaryId = data['diaryId'] as int;
final currentPlanDay = data['currentDiaryDay'] as int;
return UserDiaryScreen(
diaryId: diaryId,
currentPlanDay: currentPlanDay,
);
},
),

View File

@@ -215,7 +215,10 @@ class _BlogPostScreenState extends State<BlogPostScreen> {
child: Html(data: widget.blogPost.description, style: {"*": Style(color: Colors.black87)}),
),
const SizedBox(height: 8),
CachedNetworkImage(imageUrl: '$baseUrl/storage/${widget.blogPost.image}'),
if (widget.blogPost.image.isNotEmpty)
CachedNetworkImage(
imageUrl: '$baseUrl/storage/${widget.blogPost.image}',
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(

View File

@@ -73,7 +73,7 @@ class BlogPostRepository {
'video_url': videoUrl,
'image': image != null
? await MultipartFile.fromFile((await ImageCompressUtility.compressFile(File(image.path))).path, filename: image.name)
: oldImageUrl != null
: oldImageUrl != '' && oldImageUrl != null
? await MultipartFile.fromFile((await downloadImage(oldImageUrl))?.path ?? '', filename: oldImageUrl.split('/').last)
: null,
});

View File

@@ -28,8 +28,22 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
int currentPage = 1;
late int lastPage;
bool isLoading = false;
Timer? _timer;
ChatRoomCubit({required this.chatRepository, required this.wsManager, required this.cardsRepository}) : super(const ChatRoomState.loading());
ChatRoomCubit({
required this.chatRepository,
required this.wsManager,
required this.cardsRepository,
}) : super(const ChatRoomState.loading());
void setTimer() {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 5), (_) => updateChosenPlanState());
}
void cancelTimer() {
_timer?.cancel();
}
loadNextPage(String chatId) async {
if (currentPage < lastPage && !isLoading) {
@@ -97,7 +111,6 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
if (chosenPlan?.consultantId == chatRoom.users.sender.id) {
await checkCards();
}
} catch (e) {
log(e.toString());
typingSubscription?.cancel();
@@ -234,6 +247,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
@override
Future<void> close() async {
wsManager.unsubscribeDirectChatChannel();
_timer?.cancel();
messagesSubscription?.cancel();
typingSubscription?.cancel();
super.close();

View File

@@ -44,12 +44,24 @@ class _ChatScreenState extends State<ChatScreen> {
final List<({int id, int index})> unreadMessagesIds = [];
final List<({int id, int index})> unreadMessagesIdsCopy = [];
final showableChatBadgeStates = ChosenPlanStateEnum.getShowableChatBadgeStates();
late AppLifecycleListener _listener;
void _onHide() {
chatRoomCubit.cancelTimer();
}
void _onResume() {
chatRoomCubit.updateChosenPlanState();
chatRoomCubit.setTimer();
}
@override
void initState() {
super.initState();
scrollController.addListener(_onScroll);
chatRoomCubit.initChat(widget.chatId, sendInitialMessage: widget.sendInitialMessage ?? false);
chatRoomCubit.setTimer();
_listener = AppLifecycleListener(onHide: _onHide, onResume: _onResume);
}
_onScroll() {
@@ -61,6 +73,7 @@ class _ChatScreenState extends State<ChatScreen> {
@override
void dispose() {
scrollController.dispose();
_listener.dispose();
chatRoomCubit.close();
super.dispose();
}
@@ -96,7 +109,7 @@ class _ChatScreenState extends State<ChatScreen> {
final showAboutOrderButton =
state.chatRoom.chosenPlan != null && state.chatRoom.chosenPlan!.chosenPlanState != ChosenPlanStateEnum.stateCanceledByTheInitiator;
BannerType? bannerType;
if (chosenPlan == null) {
if (chosenPlan == null || chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateCanceledByTheInitiator) {
bannerType = null;
} else if (amIConsultant && !state.hasCard) {
bannerType = BannerType.card;

View File

@@ -197,7 +197,10 @@ class _ConsultationCardWidgetState extends State<ConsultationCardWidget> {
title: s.you_can_not_open_this_day, description: '${widget.consultationsModel.userName} ${s.has_not_filled_it_yet}');
return;
}
GoRouter.of(context).push(UserDiaryScreen.path, extra: day.$2.id);
GoRouter.of(context).push(UserDiaryScreen.path, extra: {
'diaryId': day.$2.id,
'currentDiaryDay': index + 1,
});
},
borderRadius: BorderRadius.circular(100),
child: Ink(
@@ -293,6 +296,10 @@ class _ConsultationCardWidgetState extends State<ConsultationCardWidget> {
)
.lastOrNull;
if (lastActiveDay != null) {
GoRouter.of(context).push(UserDiaryScreen.path, extra: {
'diaryId': lastActiveDay.$2.id,
'currentDiaryDay': lastActiveDay.$1,
});
GoRouter.of(context).push(UserDiaryScreen.path, extra: lastActiveDay.$2.id);
return;
}

View File

@@ -151,7 +151,7 @@ class DiaryCubit extends Cubit<DiaryState> {
return false;
}
fetchDiary([bool needLoading = false, int? diaryId]) async {
fetchDiary([bool needLoading = false, int? diaryId, int? currentDay]) async {
this.diaryId ??= diaryId;
if (needLoading) {
@@ -175,7 +175,7 @@ class DiaryCubit extends Cubit<DiaryState> {
final chosenPlanModel = await chatRepository.getChosenPlan(id: diaryDay.chosenPlanId!);
planDuration = chosenPlanModel.plan.duration;
planName = chosenPlanModel.plan.name;
currentPlanDay = DateTime.now().difference(chosenPlanModel.startDate).inDays + 1;
currentPlanDay = currentDay ?? DateTime.now().difference(chosenPlanModel.startDate).inDays + 1;
}
final nutrition = await getNutrition(diaryDay.id);

View File

@@ -2,6 +2,7 @@ import 'dart:developer';
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
@@ -34,24 +35,33 @@ class DiaryScreen extends StatelessWidget {
class UserDiaryScreen extends StatelessWidget {
static const path = '/user-diary-screen';
static const name = 'userDiaryScreen';
const UserDiaryScreen({super.key, required this.diaryId});
const UserDiaryScreen({
super.key,
required this.diaryId,
required this.currentPlanDay,
});
final int diaryId;
final int currentPlanDay;
@override
Widget build(BuildContext context) {
return DiaryScreenContent(diaryId: diaryId);
return DiaryScreenContent(
diaryId: diaryId,
currentPlanDay: currentPlanDay,
);
}
}
class DiaryScreenContent extends StatelessWidget {
const DiaryScreenContent({super.key, this.diaryId});
const DiaryScreenContent({super.key, this.diaryId, this.currentPlanDay});
final int? diaryId;
final int? currentPlanDay;
@override
Widget build(BuildContext context) {
final s = S.of(context);
return MultiBlocProvider(
providers: [
BlocProvider<DiaryCubit>(
create: (BuildContext context) => sl<DiaryCubit>()..fetchDiary(true, diaryId),
create: (BuildContext context) => sl<DiaryCubit>()..fetchDiary(true, diaryId, currentPlanDay),
),
BlocProvider(
create: (context) => sl<ConsultantCommentsCubit>(),
@@ -71,10 +81,14 @@ class DiaryScreenContent extends StatelessWidget {
return Scaffold(
backgroundColor: Colors.grey.shade200,
appBar: AppBar(
toolbarHeight: 0,
title: Text(
state is DiaryStateLoaded ? DateTime.parse(state.diary.date).toLocal().format('d MMMM') : '',
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
centerTitle: true,
),
body: SingleChildScrollView(
padding: const EdgeInsets.only(bottom: 16),
padding: const EdgeInsets.only(bottom: 16, top: 8),
physics: const BouncingScrollPhysics(),
child: Column(
children: [

View File

@@ -20,7 +20,7 @@ abstract class DietsPagination with _$DietsPagination {
abstract class Diet with _$Diet {
const factory Diet({
@JsonKey(name: "id") required int id,
@JsonKey(name: "slug") String? slug,
@JsonKey(name: "slug") required String slug,
@JsonKey(name: "name") required String name,
@JsonKey(name: "image") required String image,
@JsonKey(name: "duration") required int duration,

View File

@@ -28,10 +28,9 @@ class S {
static const AppLocalizationDelegate delegate = AppLocalizationDelegate();
static Future<S> load(Locale locale) {
final name =
(locale.countryCode?.isEmpty ?? false)
? locale.languageCode
: locale.toString();
final name = (locale.countryCode?.isEmpty ?? false)
? locale.languageCode
: locale.toString();
final localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
Intl.defaultLocale = localeName;

View File

@@ -1,6 +1,6 @@
name: eatvio_app
description: A new Flutter project.
version: 1.1.2+32
version: 1.1.3+33
publish_to: 'none'
environment: