forked from eatvio/eatvio_app
feat(oauth): Issue-691
This commit is contained in:
44
lib/features/settings/models/oauth_account_model.dart
Normal file
44
lib/features/settings/models/oauth_account_model.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'oauth_account_model.freezed.dart';
|
||||
part 'oauth_account_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class OAuthAccountModel with _$OAuthAccountModel {
|
||||
const factory OAuthAccountModel({
|
||||
@JsonKey(name: 'oauth_id') required String oauthId,
|
||||
required String name,
|
||||
required String email,
|
||||
required String phone,
|
||||
@JsonKey(name: 'linked_at') required DateTime linkedAt,
|
||||
}) = _OAuthAccountModel;
|
||||
|
||||
factory OAuthAccountModel.fromJson(Map<String, dynamic> json) => _$OAuthAccountModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class OAuthAccountsResponseModel with _$OAuthAccountsResponseModel {
|
||||
const factory OAuthAccountsResponseModel({required bool success, required OAuthAccountsDataModel data}) = _OAuthAccountsResponseModel;
|
||||
|
||||
factory OAuthAccountsResponseModel.fromJson(Map<String, dynamic> json) => _$OAuthAccountsResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class OAuthAccountsDataModel with _$OAuthAccountsDataModel {
|
||||
const factory OAuthAccountsDataModel({
|
||||
@JsonKey(fromJson: _oauthAccountFromJson) OAuthAccountModel? vk,
|
||||
@JsonKey(fromJson: _oauthAccountFromJson) OAuthAccountModel? yandex,
|
||||
}) = _OAuthAccountsDataModel;
|
||||
|
||||
factory OAuthAccountsDataModel.fromJson(Map<String, dynamic> json) => _$OAuthAccountsDataModelFromJson(json);
|
||||
}
|
||||
|
||||
// Custom converter to handle both empty array [] and object
|
||||
OAuthAccountModel? _oauthAccountFromJson(dynamic json) {
|
||||
if (json == null) return null;
|
||||
if (json is List && json.isEmpty) return null;
|
||||
if (json is Map<String, dynamic>) {
|
||||
return OAuthAccountModel.fromJson(json);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
17
lib/features/settings/models/oauth_attach_request.dart
Normal file
17
lib/features/settings/models/oauth_attach_request.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'oauth_attach_request.freezed.dart';
|
||||
part 'oauth_attach_request.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class OAuthAttachRequest with _$OAuthAttachRequest {
|
||||
const factory OAuthAttachRequest({
|
||||
required String provider,
|
||||
@JsonKey(name: 'client_id') String? clientId,
|
||||
@JsonKey(name: 'access_token') required String accessToken,
|
||||
@JsonKey(name: 'refresh_token') required String refreshToken,
|
||||
}) = _OAuthAttachRequest;
|
||||
|
||||
factory OAuthAttachRequest.fromJson(Map<String, dynamic> json) => _$OAuthAttachRequestFromJson(json);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:eatvio_app/features/consultations/repositories/consultations_rep
|
||||
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_account_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_attach_request.dart';
|
||||
import 'package:eatvio_app/features/settings/models/profile_settings_model.dart';
|
||||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart';
|
||||
import 'package:eatvio_app/features/settings/repositories/service_repository.dart';
|
||||
@@ -26,6 +28,7 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
final profile = await profileRepository.getMyProfile();
|
||||
late final ConsultationRequestModel? consultantInfo;
|
||||
late final bool hasActiveConsultation;
|
||||
late final OAuthAccountsDataModel? oauthAccounts;
|
||||
|
||||
try {
|
||||
if (profile.phoneConfirmationState.contains('confirmed')) {
|
||||
@@ -43,6 +46,13 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
hasActiveConsultation = false;
|
||||
}
|
||||
|
||||
try {
|
||||
final oauthResponse = await settingsRepository.getOAuthAccounts();
|
||||
oauthAccounts = oauthResponse.data;
|
||||
} catch (e) {
|
||||
oauthAccounts = null;
|
||||
}
|
||||
|
||||
try {
|
||||
emit(
|
||||
SettingsState.loaded(
|
||||
@@ -51,6 +61,7 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
profile: profile,
|
||||
consultationRequestModel: consultantInfo,
|
||||
hasActiveConsultation: hasActiveConsultation,
|
||||
oauthAccounts: oauthAccounts,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
@@ -87,6 +98,35 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> linkOAuthAccount({
|
||||
required String provider,
|
||||
required String accessToken,
|
||||
required String refreshToken,
|
||||
String? clientId,
|
||||
}) async {
|
||||
try {
|
||||
final request = OAuthAttachRequest(
|
||||
provider: provider,
|
||||
clientId: clientId,
|
||||
accessToken: accessToken,
|
||||
refreshToken: refreshToken,
|
||||
);
|
||||
await settingsRepository.linkOAuthAccount(request: request);
|
||||
await init();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unlinkOAuthAccount({required String provider}) async {
|
||||
try {
|
||||
await settingsRepository.unlinkOAuthAccount(provider: provider);
|
||||
await init();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _checkActiveConsultation() async {
|
||||
try {
|
||||
final userPurchases = await consultationsRepository.getUserPurchases(null, null);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_account_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/profile_settings_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@@ -17,6 +18,7 @@ abstract class SettingsState with _$SettingsState {
|
||||
required ProfileModel profile,
|
||||
ConsultationRequestModel? consultationRequestModel,
|
||||
required bool hasActiveConsultation,
|
||||
OAuthAccountsDataModel? oauthAccounts,
|
||||
}) = SettingsStateLoaded;
|
||||
|
||||
const factory SettingsState.error({
|
||||
|
||||
@@ -6,6 +6,7 @@ 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';
|
||||
import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
|
||||
import 'package:eatvio_app/features/auth/sdk/social_auth_facade.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
|
||||
import 'package:eatvio_app/features/settings/entities/settings_entity.dart';
|
||||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart';
|
||||
@@ -16,6 +17,7 @@ import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
@@ -39,12 +41,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
return AlertDialog(
|
||||
title: const Text('Предупреждение'),
|
||||
content: const Text('Во время консультации этот параметр нельзя отключить'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Понятно'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('Понятно'))],
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -80,6 +77,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_becomeConsultantButton(state),
|
||||
_deleteAccountButton(state, settingsCubit),
|
||||
_oauthAccounts(state, settingsCubit),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -328,6 +326,326 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _oauthAccounts(SettingsStateLoaded state, SettingsCubit settingsCubit) {
|
||||
final isVkLinked = state.oauthAccounts?.vk != null;
|
||||
final isYandexLinked = state.oauthAccounts?.yandex != null;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
'Привязанные аккаунты',
|
||||
style: TextStyle(fontSize: 16, height: 1, color: Colors.grey, fontFamily: 'Mulish'),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_OAuthAccountButton(
|
||||
onTap: () => _onVkPressed(state, settingsCubit),
|
||||
backgroundColor: const Color(0xFF2787F5),
|
||||
tooltip: 'VK ID',
|
||||
icon: SvgPicture.asset('assets/icons/vk_logo.svg', height: 24, width: 24),
|
||||
isLinked: isVkLinked,
|
||||
accountName: state.oauthAccounts?.vk?.name,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_OAuthAccountButton(
|
||||
onTap: () => _onOkPressed(state, settingsCubit),
|
||||
backgroundColor: const Color(0xFFF58220),
|
||||
tooltip: 'Одноклассники',
|
||||
icon: SvgPicture.asset('assets/icons/ok_logo.svg', height: 24, width: 24),
|
||||
isLinked: isVkLinked,
|
||||
accountName: state.oauthAccounts?.vk?.name,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_OAuthAccountButton(
|
||||
onTap: () => _onMailRuPressed(state, settingsCubit),
|
||||
backgroundColor: const Color(0xFF005FF9),
|
||||
tooltip: 'Mail.ru',
|
||||
icon: SvgPicture.asset('assets/icons/mail_logo.svg', height: 24, width: 24),
|
||||
isLinked: isVkLinked,
|
||||
accountName: state.oauthAccounts?.vk?.name,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_OAuthAccountButton(
|
||||
onTap: () => _onYandexPressed(state, settingsCubit),
|
||||
backgroundColor: const Color(0xFFFFCC00),
|
||||
tooltip: 'Яндекс ID',
|
||||
icon: SvgPicture.asset('assets/icons/yandex_logo.svg', height: 24, width: 24),
|
||||
isLinked: isYandexLinked,
|
||||
accountName: state.oauthAccounts?.yandex?.name,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onVkPressed(SettingsStateLoaded state, SettingsCubit settingsCubit) async {
|
||||
if (state.oauthAccounts?.vk != null) {
|
||||
// Отвязываем аккаунт
|
||||
if (!mounted) return;
|
||||
final shouldUnlink = await _showUnlinkConfirmationDialog(context, 'VK ID');
|
||||
if (shouldUnlink == true) {
|
||||
try {
|
||||
await settingsCubit.unlinkOAuthAccount(provider: 'vk');
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось отвязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mounted) return;
|
||||
|
||||
final authResult = await SocialAuthFacade.signInWithVkAndFetchProfile(context: context);
|
||||
if (authResult == null) return;
|
||||
|
||||
try {
|
||||
await settingsCubit.linkOAuthAccount(
|
||||
provider: 'vk',
|
||||
accessToken: authResult.accessToken,
|
||||
refreshToken: authResult.refreshToken ?? '',
|
||||
clientId: authResult.clientId,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onOkPressed(SettingsStateLoaded state, SettingsCubit settingsCubit) async {
|
||||
if (state.oauthAccounts?.vk != null) {
|
||||
// Отвязываем аккаунт (OK использует тот же VK ID провайдер)
|
||||
if (!mounted) return;
|
||||
final shouldUnlink = await _showUnlinkConfirmationDialog(context, 'Одноклассники');
|
||||
if (shouldUnlink == true) {
|
||||
try {
|
||||
await settingsCubit.unlinkOAuthAccount(provider: 'vk');
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось отвязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mounted) return;
|
||||
|
||||
final authResult = await SocialAuthFacade.signInWithOkAndFetchProfile();
|
||||
if (authResult == null) return;
|
||||
|
||||
try {
|
||||
await settingsCubit.linkOAuthAccount(
|
||||
provider: 'vk',
|
||||
accessToken: authResult.accessToken,
|
||||
refreshToken: authResult.refreshToken ?? '',
|
||||
clientId: authResult.clientId,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onMailRuPressed(SettingsStateLoaded state, SettingsCubit settingsCubit) async {
|
||||
if (state.oauthAccounts?.vk != null) {
|
||||
// Отвязываем аккаунт (Mail.ru использует тот же VK ID провайдер)
|
||||
if (!mounted) return;
|
||||
final shouldUnlink = await _showUnlinkConfirmationDialog(context, 'Mail.ru');
|
||||
if (shouldUnlink == true) {
|
||||
try {
|
||||
await settingsCubit.unlinkOAuthAccount(provider: 'vk');
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось отвязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mounted) return;
|
||||
|
||||
final authResult = await SocialAuthFacade.signInWithMailRuAndFetchProfile();
|
||||
if (authResult == null) return;
|
||||
|
||||
try {
|
||||
await settingsCubit.linkOAuthAccount(
|
||||
provider: 'vk',
|
||||
accessToken: authResult.accessToken,
|
||||
refreshToken: authResult.refreshToken ?? '',
|
||||
clientId: authResult.clientId,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onYandexPressed(SettingsStateLoaded state, SettingsCubit settingsCubit) async {
|
||||
if (state.oauthAccounts?.yandex != null) {
|
||||
// Отвязываем аккаунт
|
||||
if (!mounted) return;
|
||||
final shouldUnlink = await _showUnlinkConfirmationDialog(context, 'Яндекс ID');
|
||||
if (shouldUnlink == true) {
|
||||
try {
|
||||
await settingsCubit.unlinkOAuthAccount(provider: 'yandex');
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось отвязать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mounted) return;
|
||||
|
||||
final authResult = await SocialAuthFacade.signInWithYandex();
|
||||
if (authResult == null) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось авторизоваться через Яндекс');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, что refreshToken не пустой для Яндекс
|
||||
if (authResult.refreshToken == null || authResult.refreshToken!.isEmpty) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось получить токен обновления от Яндекс');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, что clientId не пустой для Яндекс
|
||||
if (authResult.clientId.isEmpty) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось получить client ID от Яндекс');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await settingsCubit.linkOAuthAccount(
|
||||
provider: 'yandex',
|
||||
accessToken: authResult.accessToken,
|
||||
refreshToken: authResult.refreshToken!,
|
||||
clientId: authResult.clientId,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorDialog(context, description: 'Не удалось привязать аккаунт: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool?> _showUnlinkConfirmationDialog(BuildContext context, String providerName) {
|
||||
return showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => CupertinoAlertDialog(
|
||||
title: const Text('Отвязать аккаунт'),
|
||||
content: Text('Вы точно хотите отвязать аккаунт $providerName?'),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
},
|
||||
child: const Text('Отмена'),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
isDestructiveAction: true,
|
||||
child: const Text('Отвязать'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _OAuthAccountButton extends StatelessWidget {
|
||||
const _OAuthAccountButton({
|
||||
required this.onTap,
|
||||
required this.icon,
|
||||
required this.backgroundColor,
|
||||
required this.tooltip,
|
||||
required this.isLinked,
|
||||
this.accountName,
|
||||
});
|
||||
|
||||
final VoidCallback onTap;
|
||||
final Widget icon;
|
||||
final Color backgroundColor;
|
||||
final String tooltip;
|
||||
final bool isLinked;
|
||||
final String? accountName;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Opacity(
|
||||
opacity: isLinked ? 0.5 : 1.0,
|
||||
child: Tooltip(
|
||||
message: tooltip,
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
onTap: onTap,
|
||||
child: Ink(
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: const Color(0xFFDBDBDB), width: 1),
|
||||
),
|
||||
child: Center(child: icon),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteAccountBottomSheet extends StatefulWidget {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_account_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_attach_request.dart';
|
||||
import 'package:eatvio_app/features/settings/models/profile_settings_model.dart';
|
||||
import 'package:eatvio_app/features/settings/services/settings_service.dart';
|
||||
|
||||
@@ -15,25 +17,41 @@ class SettingsRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<ProfileSettingsModel> updateProfileSettings({
|
||||
required ProfileSettingsModel profileSettingsModel,
|
||||
}) async {
|
||||
Future<ProfileSettingsModel> updateProfileSettings({required ProfileSettingsModel profileSettingsModel}) async {
|
||||
try {
|
||||
return await settingsService.updateProfileSettings(
|
||||
data: profileSettingsModel.toJson(),
|
||||
);
|
||||
return await settingsService.updateProfileSettings(data: profileSettingsModel.toJson());
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<ProfileDetailsModel> updateProfileDetails({
|
||||
required ProfileDetailsModel profileDetailsModel,
|
||||
}) async {
|
||||
Future<ProfileDetailsModel> updateProfileDetails({required ProfileDetailsModel profileDetailsModel}) async {
|
||||
try {
|
||||
return await settingsService.updateProfileDetails(
|
||||
data: profileDetailsModel.toJson(),
|
||||
);
|
||||
return await settingsService.updateProfileDetails(data: profileDetailsModel.toJson());
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<OAuthAccountsResponseModel> getOAuthAccounts() async {
|
||||
try {
|
||||
return await settingsService.getOAuthAccounts();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> linkOAuthAccount({required OAuthAttachRequest request}) async {
|
||||
try {
|
||||
return await settingsService.linkOAuthAccount(request);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unlinkOAuthAccount({required String provider}) async {
|
||||
try {
|
||||
return await settingsService.unlinkOAuthAccount(provider);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_account_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_attach_request.dart';
|
||||
import 'package:eatvio_app/features/settings/models/profile_settings_model.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
@@ -13,12 +15,17 @@ abstract class SettingsService {
|
||||
Future<ProfileSettingsModel> getProfileSettings();
|
||||
|
||||
@PUT('/api/profile/settings/update')
|
||||
Future<ProfileSettingsModel> updateProfileSettings({
|
||||
@Body() required Map<String, dynamic> data,
|
||||
});
|
||||
Future<ProfileSettingsModel> updateProfileSettings({@Body() required Map<String, dynamic> data});
|
||||
|
||||
@PUT('/api/profile/update')
|
||||
Future<ProfileDetailsModel> updateProfileDetails({
|
||||
@Body() required Map<String, dynamic> data,
|
||||
});
|
||||
Future<ProfileDetailsModel> updateProfileDetails({@Body() required Map<String, dynamic> data});
|
||||
|
||||
@GET('/api/oauth/accounts')
|
||||
Future<OAuthAccountsResponseModel> getOAuthAccounts();
|
||||
|
||||
@POST('/api/oauth/attach')
|
||||
Future<void> linkOAuthAccount(@Body() OAuthAttachRequest request);
|
||||
|
||||
@DELETE('/api/oauth/accounts/{provider}')
|
||||
Future<void> unlinkOAuthAccount(@Path('provider') String provider);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user