feat(feed): Dio, retrofit and freezed model stump
This commit is contained in:
@@ -3,7 +3,7 @@ import 'package:eatvio_app/locator_service.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
||||
abstract class TokenStorage {
|
||||
static addTokenToDioHeader(String token) {
|
||||
static _addTokenToDioHeader(String token) {
|
||||
sl<Dio>().options.headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
|
||||
@@ -13,20 +13,19 @@ abstract class TokenStorage {
|
||||
if (token == null) {
|
||||
return false;
|
||||
} else {
|
||||
addTokenToDioHeader(token);
|
||||
_addTokenToDioHeader(token);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static getTokenFromStorage() async => await Hive.openBox('token')
|
||||
..get('token');
|
||||
static Future<String> getTokenFromStorage() async =>
|
||||
(await Hive.openBox('token')).get('token');
|
||||
|
||||
static saveTokenInStorage(String token) async {
|
||||
await Hive.openBox('token')
|
||||
..put('token', token);
|
||||
addTokenToDioHeader(token);
|
||||
(await Hive.openBox('token')).put('token', token);
|
||||
_addTokenToDioHeader(token);
|
||||
}
|
||||
|
||||
static removeTokenInStorage(String token) async => await Hive.openBox('token')
|
||||
..delete('token');
|
||||
static removeTokenInStorage() async =>
|
||||
(await Hive.openBox('token')).delete('token');
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:eatvio_app/locator_service.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
@@ -39,7 +39,7 @@ class BlogPostCreateBloc
|
||||
blog_postModelObj: currentState.blog_postModelObj,
|
||||
title: currentState.title,
|
||||
description: currentState.description,
|
||||
youtube_url: currentState.youtube_url,
|
||||
youtubeURL: currentState.youtubeURL,
|
||||
token: currentState.token,
|
||||
),
|
||||
);
|
||||
@@ -49,7 +49,7 @@ class BlogPostCreateBloc
|
||||
token: token,
|
||||
title: TextEditingController(),
|
||||
description: TextEditingController(),
|
||||
youtube_url: TextEditingController(),
|
||||
youtubeURL: TextEditingController(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -64,8 +64,9 @@ class BlogPostCreateBloc
|
||||
|
||||
var response = await sendBlogPost(
|
||||
currentState.title?.text,
|
||||
currentState.youtube_url?.text,
|
||||
currentState.youtubeURL?.text,
|
||||
currentState.description?.text,
|
||||
currentState.image,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
@@ -78,34 +79,35 @@ class BlogPostCreateBloc
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<http.Response> sendBlogPost(
|
||||
String? title,
|
||||
String? youtube_url,
|
||||
String? description,
|
||||
) async {
|
||||
String url = '${dotenv.env['SERVER_ROOT']!}/feed/create';
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
sendBlogPost(String? title, String? youtubeURL, String? description,
|
||||
XFile? image) async {
|
||||
String url = '/blog_post/create';
|
||||
|
||||
final Map<String, dynamic> credentials = {
|
||||
'title': title,
|
||||
'description': description,
|
||||
'youtube_url': youtube_url,
|
||||
'youtube_url': youtubeURL,
|
||||
'status': 'active',
|
||||
'image': image,
|
||||
};
|
||||
|
||||
var response = await http.post(
|
||||
Uri.parse(url),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
body: json.encode(credentials),
|
||||
encoding: utf8,
|
||||
var response = await sl<Dio>().post(
|
||||
url,
|
||||
data: json.encode(credentials),
|
||||
);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
FutureOr<void> _uploadImages(
|
||||
UploadImages event, Emitter<BlogPostCreateState> emit) {}
|
||||
UploadImages event, Emitter<BlogPostCreateState> emit) {
|
||||
if (state is BlogPostCreateLoadedState) {
|
||||
var currentState = state as BlogPostCreateLoadedState;
|
||||
emit(
|
||||
currentState.copyWith(
|
||||
image: event.image,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,33 +27,37 @@ class BlogPostCreateLoadedState extends BlogPostCreateState {
|
||||
this.blog_postModelObj,
|
||||
this.title,
|
||||
this.description,
|
||||
this.youtube_url,
|
||||
this.youtubeURL,
|
||||
this.image,
|
||||
this.isLoading = false,
|
||||
});
|
||||
|
||||
BlogPostCreateModel? blog_postModelObj;
|
||||
TextEditingController? title;
|
||||
TextEditingController? description;
|
||||
TextEditingController? youtube_url;
|
||||
TextEditingController? youtubeURL;
|
||||
String? token;
|
||||
bool isLoading;
|
||||
XFile? image;
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[blog_postModelObj, title, description, youtube_url];
|
||||
[blog_postModelObj, title, description, youtubeURL];
|
||||
BlogPostCreateLoadedState copyWith({
|
||||
BlogPostCreateModel? blog_postModelObj,
|
||||
TextEditingController? title,
|
||||
TextEditingController? description,
|
||||
TextEditingController? youtube_url,
|
||||
TextEditingController? youtubeURL,
|
||||
String? token,
|
||||
XFile? image,
|
||||
bool isLoading = false,
|
||||
}) {
|
||||
return BlogPostCreateLoadedState(
|
||||
blog_postModelObj: blog_postModelObj ?? this.blog_postModelObj,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
youtube_url: youtube_url ?? this.youtube_url,
|
||||
youtubeURL: youtubeURL ?? this.youtubeURL,
|
||||
token: token ?? this.token,
|
||||
image: image ?? this.image,
|
||||
isLoading: this.isLoading,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
|
||||
import 'dart:io';
|
||||
|
||||
class BlogPostCreateScreen extends StatelessWidget {
|
||||
const BlogPostCreateScreen({Key? key}) : super(key: key);
|
||||
@@ -43,6 +44,7 @@ class BlogPostCreateScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
_buildBlogPostCreate(BuildContext context, BlogPostCreateLoadedState state) {
|
||||
print(state.image);
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
@@ -85,7 +87,7 @@ class BlogPostCreateScreen extends StatelessWidget {
|
||||
Text("Ссылка на YouTube",
|
||||
style: theme.textTheme.bodyLarge),
|
||||
CustomTextFormField(
|
||||
controller: state.youtube_url,
|
||||
controller: state.youtubeURL,
|
||||
validator: _validateYouTubeLink,
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
@@ -101,7 +103,7 @@ class BlogPostCreateScreen extends StatelessWidget {
|
||||
// Add widget for image upload here
|
||||
CustomOutlinedButton(
|
||||
onPressed: () => _submitForm(context, state.title!.text,
|
||||
state.description!.text, state.youtube_url!.text),
|
||||
state.description!.text, state.youtubeURL!.text),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
text: 'Создать',
|
||||
),
|
||||
@@ -144,7 +146,7 @@ _buildAddPhoto(BuildContext context, BlogPostCreateLoadedState state) {
|
||||
onTap: addImage(context, isLoading),
|
||||
child: Stack(
|
||||
children: [
|
||||
if (!isLoading)
|
||||
if (state.image == null)
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 10.h),
|
||||
padding: EdgeInsets.symmetric(
|
||||
@@ -158,8 +160,6 @@ _buildAddPhoto(BuildContext context, BlogPostCreateLoadedState state) {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Показывайте прелоадер, если загрузка активна
|
||||
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 7.h,
|
||||
@@ -178,7 +178,7 @@ _buildAddPhoto(BuildContext context, BlogPostCreateLoadedState state) {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isLoading)
|
||||
if (state.image != null)
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 10.h),
|
||||
padding: EdgeInsets.symmetric(
|
||||
@@ -188,12 +188,8 @@ _buildAddPhoto(BuildContext context, BlogPostCreateLoadedState state) {
|
||||
decoration: AppDecoration.fillGray.copyWith(
|
||||
borderRadius: BorderRadiusStyle.roundedBorder5,
|
||||
),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: appTheme
|
||||
.blueGray300), // Замените на свой прелоадер при необходимости
|
||||
),
|
||||
),
|
||||
child: Image(image: FileImage(File(state.image!.path))),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'blog_post_create_credentials_model.freezed.dart';
|
||||
part 'blog_post_create_credentials_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class BlogPostCreateCredentialsModel with _$BlogPostCreateCredentialsModel {
|
||||
const factory BlogPostCreateCredentialsModel({
|
||||
required String title,
|
||||
required String description,
|
||||
@JsonKey(name: 'youtube_url') required String youtubeUrl,
|
||||
@Default('active') String status,
|
||||
}) = _BlogPostCreateCredentialsModel;
|
||||
|
||||
factory BlogPostCreateCredentialsModel.fromJson(Map<String, Object?> json) =>
|
||||
_$BlogPostCreateCredentialsModelFromJson(json);
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'blog_post_create_credentials_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
BlogPostCreateCredentialsModel _$BlogPostCreateCredentialsModelFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return _BlogPostCreateCredentialsModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$BlogPostCreateCredentialsModel {
|
||||
String get title => throw _privateConstructorUsedError;
|
||||
String get description => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'youtube_url')
|
||||
String get youtubeUrl => throw _privateConstructorUsedError;
|
||||
String get status => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$BlogPostCreateCredentialsModelCopyWith<BlogPostCreateCredentialsModel>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $BlogPostCreateCredentialsModelCopyWith<$Res> {
|
||||
factory $BlogPostCreateCredentialsModelCopyWith(
|
||||
BlogPostCreateCredentialsModel value,
|
||||
$Res Function(BlogPostCreateCredentialsModel) then) =
|
||||
_$BlogPostCreateCredentialsModelCopyWithImpl<$Res,
|
||||
BlogPostCreateCredentialsModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{String title,
|
||||
String description,
|
||||
@JsonKey(name: 'youtube_url') String youtubeUrl,
|
||||
String status});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$BlogPostCreateCredentialsModelCopyWithImpl<$Res,
|
||||
$Val extends BlogPostCreateCredentialsModel>
|
||||
implements $BlogPostCreateCredentialsModelCopyWith<$Res> {
|
||||
_$BlogPostCreateCredentialsModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? title = null,
|
||||
Object? description = null,
|
||||
Object? youtubeUrl = null,
|
||||
Object? status = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
youtubeUrl: null == youtubeUrl
|
||||
? _value.youtubeUrl
|
||||
: youtubeUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
status: null == status
|
||||
? _value.status
|
||||
: status // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BlogPostCreateCredentialsModelImplCopyWith<$Res>
|
||||
implements $BlogPostCreateCredentialsModelCopyWith<$Res> {
|
||||
factory _$$BlogPostCreateCredentialsModelImplCopyWith(
|
||||
_$BlogPostCreateCredentialsModelImpl value,
|
||||
$Res Function(_$BlogPostCreateCredentialsModelImpl) then) =
|
||||
__$$BlogPostCreateCredentialsModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{String title,
|
||||
String description,
|
||||
@JsonKey(name: 'youtube_url') String youtubeUrl,
|
||||
String status});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostCreateCredentialsModelImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostCreateCredentialsModelCopyWithImpl<$Res,
|
||||
_$BlogPostCreateCredentialsModelImpl>
|
||||
implements _$$BlogPostCreateCredentialsModelImplCopyWith<$Res> {
|
||||
__$$BlogPostCreateCredentialsModelImplCopyWithImpl(
|
||||
_$BlogPostCreateCredentialsModelImpl _value,
|
||||
$Res Function(_$BlogPostCreateCredentialsModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? title = null,
|
||||
Object? description = null,
|
||||
Object? youtubeUrl = null,
|
||||
Object? status = null,
|
||||
}) {
|
||||
return _then(_$BlogPostCreateCredentialsModelImpl(
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
youtubeUrl: null == youtubeUrl
|
||||
? _value.youtubeUrl
|
||||
: youtubeUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
status: null == status
|
||||
? _value.status
|
||||
: status // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$BlogPostCreateCredentialsModelImpl
|
||||
implements _BlogPostCreateCredentialsModel {
|
||||
const _$BlogPostCreateCredentialsModelImpl(
|
||||
{required this.title,
|
||||
required this.description,
|
||||
@JsonKey(name: 'youtube_url') required this.youtubeUrl,
|
||||
this.status = 'active'});
|
||||
|
||||
factory _$BlogPostCreateCredentialsModelImpl.fromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$$BlogPostCreateCredentialsModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String title;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
@JsonKey(name: 'youtube_url')
|
||||
final String youtubeUrl;
|
||||
@override
|
||||
@JsonKey()
|
||||
final String status;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BlogPostCreateCredentialsModel(title: $title, description: $description, youtubeUrl: $youtubeUrl, status: $status)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BlogPostCreateCredentialsModelImpl &&
|
||||
(identical(other.title, title) || other.title == title) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.youtubeUrl, youtubeUrl) ||
|
||||
other.youtubeUrl == youtubeUrl) &&
|
||||
(identical(other.status, status) || other.status == status));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, title, description, youtubeUrl, status);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$BlogPostCreateCredentialsModelImplCopyWith<
|
||||
_$BlogPostCreateCredentialsModelImpl>
|
||||
get copyWith => __$$BlogPostCreateCredentialsModelImplCopyWithImpl<
|
||||
_$BlogPostCreateCredentialsModelImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$BlogPostCreateCredentialsModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _BlogPostCreateCredentialsModel
|
||||
implements BlogPostCreateCredentialsModel {
|
||||
const factory _BlogPostCreateCredentialsModel(
|
||||
{required final String title,
|
||||
required final String description,
|
||||
@JsonKey(name: 'youtube_url') required final String youtubeUrl,
|
||||
final String status}) = _$BlogPostCreateCredentialsModelImpl;
|
||||
|
||||
factory _BlogPostCreateCredentialsModel.fromJson(Map<String, dynamic> json) =
|
||||
_$BlogPostCreateCredentialsModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get title;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
@JsonKey(name: 'youtube_url')
|
||||
String get youtubeUrl;
|
||||
@override
|
||||
String get status;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$BlogPostCreateCredentialsModelImplCopyWith<
|
||||
_$BlogPostCreateCredentialsModelImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'blog_post_create_credentials_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$BlogPostCreateCredentialsModelImpl
|
||||
_$$BlogPostCreateCredentialsModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$BlogPostCreateCredentialsModelImpl(
|
||||
title: json['title'] as String,
|
||||
description: json['description'] as String,
|
||||
youtubeUrl: json['youtube_url'] as String,
|
||||
status: json['status'] as String? ?? 'active',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$BlogPostCreateCredentialsModelImplToJson(
|
||||
_$BlogPostCreateCredentialsModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'description': instance.description,
|
||||
'youtube_url': instance.youtubeUrl,
|
||||
'status': instance.status,
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/services/blog_service.dart';
|
||||
|
||||
class BlogRepository {
|
||||
final BlogService blogService;
|
||||
|
||||
BlogRepository({
|
||||
required this.blogService,
|
||||
});
|
||||
|
||||
Future<BlogPostCreateCredentialsModel> createBlogPost(
|
||||
BlogPostCreateCredentialsModel model) async {
|
||||
try {
|
||||
return (await blogService.createBlogPost(model));
|
||||
} catch (e) {
|
||||
print(e);
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
part 'blog_service.g.dart';
|
||||
|
||||
@RestApi()
|
||||
abstract class BlogService {
|
||||
factory BlogService(Dio dio, {String baseUrl}) = _BlogService;
|
||||
|
||||
@POST('/blog_post/create')
|
||||
Future<BlogPostCreateCredentialsModel> createBlogPost(
|
||||
BlogPostCreateCredentialsModel model);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'blog_service.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RetrofitGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
|
||||
|
||||
class _BlogService implements BlogService {
|
||||
_BlogService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
String? baseUrl;
|
||||
|
||||
@override
|
||||
Future<BlogPostCreateCredentialsModel> createBlogPost(
|
||||
BlogPostCreateCredentialsModel model) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(
|
||||
_setStreamType<BlogPostCreateCredentialsModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/blog_post/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
))));
|
||||
final value = BlogPostCreateCredentialsModel.fromJson(_result.data!);
|
||||
return value;
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
requestOptions.responseType == ResponseType.stream)) {
|
||||
if (T == String) {
|
||||
requestOptions.responseType = ResponseType.plain;
|
||||
} else {
|
||||
requestOptions.responseType = ResponseType.json;
|
||||
}
|
||||
}
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
final url = Uri.parse(baseUrl);
|
||||
|
||||
if (url.isAbsolute) {
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
return Uri.parse(dioBaseUrl).resolveUri(url).toString();
|
||||
}
|
||||
}
|
||||
@@ -44,22 +44,29 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
if (data is Map<String, dynamic>) {
|
||||
if (state is BlogPostEditLoadedState) {
|
||||
var currentState = state as BlogPostEditLoadedState;
|
||||
emit(currentState.copyWith(
|
||||
emit(
|
||||
currentState.copyWith(
|
||||
blog_postModelObj: currentState.blog_postModelObj,
|
||||
blog_post: currentState.blog_post,
|
||||
title: currentState.title,
|
||||
description: currentState.description,
|
||||
youtube_url: currentState.youtube_url,),);
|
||||
youtubeURL: currentState.youtubeURL,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
emit(BlogPostEditLoadedState(
|
||||
emit(
|
||||
BlogPostEditLoadedState(
|
||||
blog_post: data,
|
||||
title: TextEditingController(text: data['title']),
|
||||
description: TextEditingController(text: data['description']),
|
||||
youtube_url: TextEditingController(text: data['youtube_url']),),);
|
||||
youtubeURL: TextEditingController(text: data['youtubeURL']),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
emit(BlogPostEditErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
emit(BlogPostEditErrorState(
|
||||
'Некоторые необходимые данные отсутствуют.'));
|
||||
}
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
@@ -71,21 +78,24 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _editBlogPost(EditBlogPost event, Emitter<BlogPostEditState> emit) async {
|
||||
FutureOr<void> _editBlogPost(
|
||||
EditBlogPost event, Emitter<BlogPostEditState> emit) async {
|
||||
if (state is BlogPostEditLoadedState) {
|
||||
var currentState = state as BlogPostEditLoadedState;
|
||||
|
||||
var response = await sendBlogPost(
|
||||
currentState.blog_post,
|
||||
currentState.title?.text,
|
||||
currentState.youtube_url?.text,
|
||||
currentState.youtubeURL?.text,
|
||||
currentState.description?.text,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('blogPostScreen', extra: currentState.blog_post?['id'].toString());
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('blogPostScreen',
|
||||
extra: currentState.blog_post?['id'].toString());
|
||||
} else {
|
||||
print('Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
print(
|
||||
'Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +103,7 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
FutureOr<http.Response> sendBlogPost(
|
||||
Map<String, dynamic>? blog_post,
|
||||
String? title,
|
||||
String? youtube_url,
|
||||
String? youtubeURL,
|
||||
String? description,
|
||||
) async {
|
||||
int id = blog_post?['id'];
|
||||
@@ -103,7 +113,7 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'youtube_url': youtube_url,
|
||||
'youtubeURL': youtubeURL,
|
||||
};
|
||||
|
||||
var response = await http.post(
|
||||
|
||||
@@ -22,34 +22,35 @@ class BlogPostEditState extends Equatable {
|
||||
}
|
||||
|
||||
class BlogPostEditLoadedState extends BlogPostEditState {
|
||||
BlogPostEditLoadedState(
|
||||
{this.blog_postModelObj,
|
||||
this.blog_post,
|
||||
this.title,
|
||||
this.description,
|
||||
this.youtube_url,});
|
||||
BlogPostEditLoadedState({
|
||||
this.blog_postModelObj,
|
||||
this.blog_post,
|
||||
this.title,
|
||||
this.description,
|
||||
this.youtubeURL,
|
||||
});
|
||||
|
||||
BlogPostEditModel? blog_postModelObj;
|
||||
Map<String, dynamic>? blog_post;
|
||||
TextEditingController? title;
|
||||
TextEditingController? description;
|
||||
TextEditingController? youtube_url;
|
||||
TextEditingController? youtubeURL;
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[blog_postModelObj, blog_post, title, description, youtube_url];
|
||||
[blog_postModelObj, blog_post, title, description, youtubeURL];
|
||||
BlogPostEditLoadedState copyWith({
|
||||
BlogPostEditModel? blog_postModelObj,
|
||||
Map<String, dynamic>? blog_post,
|
||||
TextEditingController? title,
|
||||
TextEditingController? description,
|
||||
TextEditingController? youtube_url,
|
||||
TextEditingController? youtubeURL,
|
||||
}) {
|
||||
return BlogPostEditLoadedState(
|
||||
blog_postModelObj: blog_postModelObj ?? this.blog_postModelObj,
|
||||
blog_post: blog_post ?? this.blog_post,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
youtube_url: youtube_url ?? this.youtube_url,
|
||||
youtubeURL: youtubeURL ?? this.youtubeURL,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,12 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
|
||||
static Widget builder(BuildContext context, blog_postID) {
|
||||
return BlocProvider<BlogPostEditBloc>(
|
||||
create: (context) =>
|
||||
BlogPostEditBloc(BlogPostEditState(blog_postModelObj: BlogPostEditModel(blog_postID: blog_postID.toString())))..add(BlogPostEditInitialEvent()),
|
||||
child: BlogPostEditScreen(),);
|
||||
create: (context) => BlogPostEditBloc(BlogPostEditState(
|
||||
blog_postModelObj:
|
||||
BlogPostEditModel(blog_postID: blog_postID.toString())))
|
||||
..add(BlogPostEditInitialEvent()),
|
||||
child: BlogPostEditScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
@@ -74,7 +77,8 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.blog_post?['image'] ?? ''),
|
||||
imageUrl: dotenv.env['STORAGE_URL']! +
|
||||
(state.blog_post?['image'] ?? ''),
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
@@ -98,13 +102,14 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.youtube_url,
|
||||
controller: state.youtubeURL,
|
||||
decoration: InputDecoration(labelText: 'Ссылка'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
// Здесь нужно добавить виджет для загрузки картинки
|
||||
ElevatedButton(
|
||||
onPressed: () => context.read<BlogPostEditBloc>().add(EditBlogPost()),
|
||||
onPressed: () =>
|
||||
context.read<BlogPostEditBloc>().add(EditBlogPost()),
|
||||
child: Text('Сохранить'),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user