repository

์šฉ๋„

network ์—์„œ ๋งŒ๋“ค์–ด์ค€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ํ†ตํ•ด์„œ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๋Š” ์ฑ…์ž„์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋‹ค. ๋„๋ฉ”์ธ ๋ณ„๋กœ ๋‚˜๋ˆ ์„œ ๊ฐ ๋„๋ฉ”์ธ์— ๋Œ€ํ•ด์„œ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋“ฑ์˜ ์ฑ…์ž„์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๊ตฌํ˜„

ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜ ๊ฐ•์˜์—์„œ dartz ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ์ฒ˜์Œ์—” ์ข€ ์ด์ƒํ•˜๋‹ค ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ๋ง‰์ƒ ํ”„๋กœ์ ํŠธ์— ์จ๋ณด๋‹ˆ ์—๋Ÿฌ ๋‚ฌ์„๋•Œ์™€ ์ •์ƒ ์ฒ˜๋ฆฌ๋ฅผ ๋” ๋ถ„๋ช…ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•˜๋‹ค.

flutter pub add dartz
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';

import '../../../../barrel.dart';

class UserRepositoryImpl extends UserRepository {
  final Dio apiClient;
  final ConnectionManager connectionManager;

  UserRepositoryImpl({
    required this.apiClient,
    required this.connectionManager,
  });

  @override
  Future<Either<AppException, bool>> replaceIsPushPermitted(
      bool isPushPermitted) async {
    final togglePushPermittedRequest =
        apiClient.put('/user/push-permitted', queryParameters: {
      'isPushPermitted': isPushPermitted,
    });
    try {
      Response response = await togglePushPermittedRequest;
      return Right(response.data['isPushPermitted'] as bool);
    } catch (error) {
      return Left(
          AppException(TextManager.notificationToggleFailedMessage.tr()));
    }
  }

  @override
  Future<Either<AppException, void>> replacePushToken(String pushToken) async {
    final replacePushTokenRequest = apiClient.put('/user/push-token');
    try {
      await replacePushTokenRequest;
      return const Right(null);
    } catch (error) {
      return Left(AppException.basicError());
    }
  }

  @override
  Future<Either<AppException, bool>> appVersionCheck() async {
    final appVersionCheck = apiClient.get('/app/version');

    try {
      final Response response = await appVersionCheck;
      return Right(response.data['isForceUpdate']);
    } catch (error) {
      return Left(AppException(TextManager.appVersionCheckFailedMessage.tr()));
    }
  }

  @override
  Future<Either<AppException, void>> updateProfile(
      UpdateProfileCommand command) async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final Map<String, dynamic> jsonData = command.toJson();
    final FormData formData;
    if (command.profileImage != null) {
      formData = FormData.fromMap({
        'profileImage':
            await MultipartFile.fromFile(command.profileImage!.path),
      });

      jsonData.forEach((key, value) {
        formData.fields.add(MapEntry(key, value.toString()));
      });
    } else {
      formData = FormData.fromMap(jsonData);
    }

    try {
      await apiClient.put(
        '/user/profile',
        data: formData,
        options: Options(
          contentType: 'multipart/form-data',
        ),
      );
      return const Right(null);
    } on DioException catch (error) {
      return Left(AppException(TextManager.updateProfileFailedMessage.tr()));
    }
  }

  @override
  Future<Either<AppException, void>> quitService() async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final minimumLatency = Future.delayed(const Duration(milliseconds: 700));
    final quitServiceRequest = apiClient.delete('/user/quit');
    try {
      await Future.wait([minimumLatency, quitServiceRequest]);
      return const Right(null);
    } catch (error) {
      return Left(AppException(TextManager.quitServiceFailedMessage.tr()));
    }
  }

  @override
  Future<Either<AppException, UserDetailModel>> getUserDetail() async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final minimumLatency = Future.delayed(const Duration(milliseconds: 700));
    final getUserDetailRequest = apiClient.get('/user/profile');
    try {
      await Future.wait([minimumLatency, getUserDetailRequest]);
      Response response = await getUserDetailRequest;
      UserDetailModel result = UserDetailModel.fromJson(response.data);

      return Right(result);
    } catch (error) {
      return Left(AppException(TextManager.userDetailFailedMessage.tr()));
    }
  }

  @override
  Future<Either<AppException, SignInResponse>> signIn() async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final minimumLatency = Future.delayed(const Duration(milliseconds: 700));
    final signInRequest = apiClient.post('/user/token');
    try {
      await Future.wait([minimumLatency, signInRequest]);
    } catch (error) {
      return Left(AppException(TextManager.signInFailed.tr()));
    }
    Response signInResponse = await signInRequest;

    return Right(SignInResponse.fromJson(signInResponse.data));
  }

  @override
  Future<Either<AppException, SignInResponse>> continueWithSocial(
      ContinueWithSocialQuery continueWithSocialQuery) async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final minimumLatency = Future.delayed(const Duration(milliseconds: 700));
    final continueWithSocialRequest =
        apiClient.post('/user', data: continueWithSocialQuery.toJson());

    try {
      await Future.wait([minimumLatency, continueWithSocialRequest]);
    } on DioException catch (error) {
      return Left(AppException(TextManager.continueWithSocialFailed.tr()));
    }
    final Response continueWithSocialResponse = await continueWithSocialRequest;

    return Right(SignInResponse.fromJson(continueWithSocialResponse.data));
  }

  @override
  Future<Either<AppException, void>> completeOnBoarding(
      CompleteOnBoardingCommand command) async {
    bool isConnected = await connectionManager.isConnected;
    if (!isConnected) {
      return Left(AppException(TextManager.internetNotConnected.tr()));
    }

    final Map<String, dynamic> jsonData = command.toJson();
    final FormData formData;
    if (command.profileImage != null) {
      formData = FormData.fromMap({
        'profileImage':
            await MultipartFile.fromFile(command.profileImage!.path),
      });

      jsonData.forEach((key, value) {
        formData.fields.add(MapEntry(key, value.toString()));
      });
    } else {
      formData = FormData.fromMap(jsonData);
    }

    try {
      await apiClient.post(
        '/user/profile',
        data: formData,
        options: Options(
          contentType: 'multipart/form-data',
        ),
      );
      return const Right(null);
    } on DioException catch (error) {
      return Left(
          AppException(TextManager.onboardingFailedExceptionContents.tr()));
    }
  }
}

๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํ†ต์‹  ์ผ€์ด์Šค๊ฐ€ ์žˆ์–ด์„œ ์ผ๋‹จ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค ๊ฐ€์ ธ์™”๋‹ค. ํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค, ๊ตฌํ˜„์ฒด๋ฅผ ๋‚˜๋ˆ„์ง€ ์•Š๊ณ  data ๋ ˆ์ด์–ด์— ๋ฐ”๋กœ ๊ตฌํ˜„์ฒด ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด๋‹ค.

์‚ฌ์šฉ

  static _registerRepositories() async {
    GetIt.instance.registerLazySingleton<UserRepository>(
      () => UserRepository(
        apiClient: apiClient,
        connectionManager: connectionManager,
      ),
    );
  }

๋‹ค๋ฅธ ๊ฒƒ๋“ค๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Injector ์— ์œ„์™€ ๊ฐ™์ด ์„ ์–ธํ•œ ํ›„ ํ•„์š”ํ•œ ๋•Œ(= Bloc ์— ์ฃผ์ž…) ์‚ฌ์šฉํ•œ๋‹ค.

Last updated