Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/appleid_button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions lib/core/constants/endpoint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class Endpoint {

static get updateDefaultPreparation => _defaultPreparation;

static const _updateSpareTime = '/users/me/spare-time';
static get updateSpareTime => _updateSpareTime;

static const _fcmToken = '/firebase-token'; // 사용자 fcm 토큰 등록
static get fcmTokenRegister => _fcmToken;
}
21 changes: 20 additions & 1 deletion lib/data/data_sources/preparation_remote_data_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:on_time_front/domain/entities/preparation_entity.dart';
import 'package:on_time_front/data/models/create_preparation_schedule_request_model.dart';
import 'package:on_time_front/data/models/create_defualt_preparation_request_model.dart';
import 'package:on_time_front/data/models/get_preparation_step_response_model.dart';
import 'package:on_time_front/data/models/update_spare_time_request_model.dart';

abstract interface class PreparationRemoteDataSource {
Future<void> createDefaultPreparation(
Expand All @@ -24,6 +25,8 @@ abstract interface class PreparationRemoteDataSource {
Future<PreparationEntity> getPreparationByScheduleId(String scheduleId);

Future<PreparationEntity> getDefualtPreparation();

Future<void> updateSpareTime(Duration newSpareTime);
}

@Injectable(as: PreparationRemoteDataSource)
Expand Down Expand Up @@ -121,7 +124,7 @@ class PreparationRemoteDataSourceImpl implements PreparationRemoteDataSource {
PreparationUserModifyRequestModelListExtension.fromEntityList(
preparationEntity.preparationStepList);

final result = await dio.post(
final result = await dio.put(
Endpoint.updateDefaultPreparation,
data: updateModel.map((model) => model.toJson()).toList(),
);
Expand Down Expand Up @@ -154,4 +157,20 @@ class PreparationRemoteDataSourceImpl implements PreparationRemoteDataSource {
rethrow;
}
}

@override
Future<void> updateSpareTime(Duration newSpareTime) async {
try {
final body = UpdateSpareTimeRequestModel.fromDuration(newSpareTime);
final result = await dio.put(
Endpoint.updateSpareTime,
data: body.toJson(),
);
if (result.statusCode != 200) {
throw Exception('Error updating spare time');
}
} catch (e) {
rethrow;
}
}
}
13 changes: 13 additions & 0 deletions lib/data/models/update_spare_time_request_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class UpdateSpareTimeRequestModel {
final int newSpareTime;

UpdateSpareTimeRequestModel({required this.newSpareTime});

Map<String, dynamic> toJson() => {
'newSpareTime': newSpareTime,
};

factory UpdateSpareTimeRequestModel.fromDuration(Duration duration) {
return UpdateSpareTimeRequestModel(newSpareTime: duration.inMinutes);
}
}
8 changes: 8 additions & 0 deletions lib/data/repositories/preparation_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,12 @@ class PreparationRepositoryImpl implements PreparationRepository {
rethrow;
}
}

Future<void> updateSpareTime(Duration newSpareTime) async {
try {
await preparationRemoteDataSource.updateSpareTime(newSpareTime);
} catch (e) {
rethrow;
}
}
}
10 changes: 10 additions & 0 deletions lib/data/repositories/user_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ class UserRepositoryImpl implements UserRepository {
}
}

@override
Future<void> disconnectGoogleSignIn() async {
try {
await _googleSignIn.disconnect();
debugPrint('Google Sign-In disconnected');
} catch (e) {
debugPrint('Google Sign-In disconnect failed: $e');
}
}

@override
Stream<UserEntity> get userStream =>
_userStreamController.asBroadcastStream();
Expand Down
2 changes: 2 additions & 0 deletions lib/domain/repositories/preparation_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ abstract interface class PreparationRepository {

Future<void> updatePreparationByScheduleId(
PreparationEntity preparationEntity, String scheduleId);

Future<void> updateSpareTime(Duration newSpareTime);
}
2 changes: 2 additions & 0 deletions lib/domain/repositories/user_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ abstract interface class UserRepository {
Future<void> postFeedback(String message);

Future<String?> getUserSocialType();

Future<void> disconnectGoogleSignIn();
}
2 changes: 2 additions & 0 deletions lib/domain/use-cases/delete_user_use_case.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class DeleteUserUseCase {

final socialTypeString = await _userRepository.getUserSocialType();
final socialType = socialTypeFromString(socialTypeString);

if (socialType == SocialType.google) {
await _userRepository.disconnectGoogleSignIn();
await _userRepository.deleteGoogleUser();
} else if (socialType == SocialType.apple) {
await _userRepository.deleteAppleUser();
Expand Down
13 changes: 13 additions & 0 deletions lib/domain/use-cases/update_spare_time_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:injectable/injectable.dart';
import 'package:on_time_front/domain/repositories/preparation_repository.dart';

@Injectable()
class UpdateSpareTimeUseCase {
final PreparationRepository _preparationRepository;

UpdateSpareTimeUseCase(this._preparationRepository);

Future<void> call(Duration newSpareTime) async {
await _preparationRepository.updateSpareTime(newSpareTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ class AppleSignInButton extends StatelessWidget {

return SizedBox(
width: 358,
child: DefaultTextStyle.merge(
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.w600,
height: 24 / 19,
fontFamily: 'SF Pro',
),
child: SignInWithAppleButton(
onPressed: () async {
height: 54,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () async {
try {
final credential = await SignInWithApple.getAppleIDCredential(
scopes: [
Expand Down Expand Up @@ -51,11 +47,14 @@ class AppleSignInButton extends StatelessWidget {
debugPrint('Apple Sign In Error: ${e.toString()}');
}
},
style: SignInWithAppleButtonStyle.black,
height: 54,
borderRadius: BorderRadius.circular(14),
iconAlignment: IconAlignment.center,
text: 'Sign in with Apple',
child: Image.asset(
'appleid_button.png',
package: 'assets',
width: 358,
height: 54,
fit: BoxFit.cover,
),
),
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,64 @@ import 'package:on_time_front/core/di/di_setup.dart';
import 'package:on_time_front/domain/repositories/user_repository.dart';

class GoogleSignInButton extends StatelessWidget {
GoogleSignInButton({super.key});

final Widget googleIconSvg = SvgPicture.asset(
'google_icon.svg',
package: 'assets',
semanticsLabel: 'Google Icon',
fit: BoxFit.contain,
);
const GoogleSignInButton({super.key});

@override
Widget build(BuildContext context) {
final UserRepository authenticationRepository = getIt.get<UserRepository>();
return GestureDetector(
onTap: () async {
try {
final googleAccout =
await authenticationRepository.googleSignIn.signIn();
if (googleAccout == null) {
throw Exception('Google Sign In Failed, Sign In Accout is null');

return SizedBox(
width: 358,
height: 54,
child: ElevatedButton(
onPressed: () async {
try {
final googleAccount =
await authenticationRepository.googleSignIn.signIn();
if (googleAccount == null) {
throw Exception('Google Sign In Failed, Sign In Account is null');
}
await authenticationRepository.signInWithGoogle(googleAccount);
} catch (e) {
debugPrint(e.toString());
}
await authenticationRepository.signInWithGoogle(googleAccout);
} catch (e) {
debugPrint(e.toString());
}
},
child: Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Color(0xFF747775)),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 2,
offset: Offset(0, 1),
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
elevation: 1,
shadowColor: Colors.black26,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: Color(0xFFDADCE0), width: 1),
),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'google_icon.svg',
package: 'assets',
semanticsLabel: 'Google Icon',
fit: BoxFit.contain,
width: 20,
height: 20,
),
SizedBox(width: 10),
Text(
'Sign in with Google',
style: TextStyle(
fontFamily: 'Pretendard',
fontWeight: FontWeight.w600,
fontSize: 21,
height: 1.4,
letterSpacing: 0,
color: Colors.black87,
),
),
],
),
child: Padding(
padding: const EdgeInsets.all(9.0),
child: googleIconSvg,
),
),
);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/presentation/login/screens/sign_in_main_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class _SignInMainScreenState extends State<SignInMainScreen> {
SizedBox(height: 41),
if (!kIsWeb && Platform.isIOS) ...[
AppleSignInButton(),
SizedBox(height: 22),
SizedBox(height: 16),
],
GoogleSignInButton(),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import 'package:equatable/equatable.dart';
import 'package:injectable/injectable.dart';
import 'package:on_time_front/domain/entities/preparation_entity.dart';
import 'package:on_time_front/domain/use-cases/get_default_preparation_use_case.dart';
import 'package:on_time_front/domain/use-cases/onboard_use_case.dart';
import 'package:on_time_front/domain/use-cases/update_default_preparation_use_case.dart';
import 'package:on_time_front/domain/use-cases/update_spare_time_use_case.dart';
import 'package:on_time_front/domain/use-cases/load_user_use_case.dart';

part 'default_preparation_spare_time_form_event.dart';
part 'default_preparation_spare_time_form_state.dart';
Expand All @@ -14,7 +16,9 @@ class DefaultPreparationSpareTimeFormBloc extends Bloc<
DefaultPreparationSpareTimeFormState> {
DefaultPreparationSpareTimeFormBloc(
this._getDefaultPreparationUseCase,
this._onboardUseCase,
this._updateDefaultPreparationUseCase,
this._updateSpareTimeUseCase,
this._loadUserUseCase,
) : super(DefaultPreparationSpareTimeFormState()) {
on<FormEditRequested>(_onFormEditRequested);
on<SpareTimeIncreased>(_onSpareTimeIncreased);
Expand All @@ -23,7 +27,9 @@ class DefaultPreparationSpareTimeFormBloc extends Bloc<
}

final GetDefaultPreparationUseCase _getDefaultPreparationUseCase;
final OnboardUseCase _onboardUseCase;
final UpdateDefaultPreparationUseCase _updateDefaultPreparationUseCase;
final UpdateSpareTimeUseCase _updateSpareTimeUseCase;
final LoadUserUseCase _loadUserUseCase;
final Duration lowerBound = Duration(minutes: 10);
final Duration stepSize = Duration(minutes: 5);

Expand Down Expand Up @@ -78,11 +84,9 @@ class DefaultPreparationSpareTimeFormBloc extends Bloc<
));

try {
await _onboardUseCase(
preparationEntity: event.preparation,
spareTime: state.spareTime!,
note: event.note,
);
await _updateDefaultPreparationUseCase(event.preparation);
await _updateSpareTimeUseCase(state.spareTime!);
await _loadUserUseCase();

emit(state.copyWith(
status: DefaultPreparationSpareTimeStatus.success,
Expand Down
Loading