Skip to content
Merged
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
38 changes: 19 additions & 19 deletions .firebase/hosting.YnVpbGQvd2Vi.cache
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
sqlite3.wasm,1741271571761,8e9753999ba85942d1a9a6c04be82ee46302f3a1f0aeba058a7bebae30841625
manifest.json,1741334354549,d140e9b4ee89585110795b5694c8810100fa767bcaae0ccd87eff4c913d13ad5
main.dart.js,1741607022628,8bf43807bc9004d23189f50db7c3d2c28525da836241aba25e0687755cd3ad99
functions.js,1741606095420,1c05c6a75b8f0038c721fa77d561c915f634e3736e1414cf0927237bbdbceb4f
manifest.json,1742052616326,d140e9b4ee89585110795b5694c8810100fa767bcaae0ccd87eff4c913d13ad5
main.dart.js,1742190209674,a3b8a795e9b34e847e39638e72a5560f5fa0c01c45de09238d9d02cf7de4e2a1
functions.js,1742052626416,c1c285b00096d7fef7dd8c06d7613cb917b93a3038a83f9be2783cc251fdd25f
flutter.js,1738903988000,8d47a0ef2a70705bf7e18df9c5148574acdff9bc412554b0784f1f46ba5918a4
favicon.png,1738903832254,fcc7c4545d5b62ad01682589e6fdc7ea03d0a3b42069963c815c344b632eb5cf
firebase-messaging-sw.js,1742052626416,eedb577a90ce796089ee56fbe936247b155b7de5f3ba19d4717b71b4bad8c426
drift_worker.dart.js,1741271571758,06ac27c648f4e1b3d5f75980fd2ffd502e43ab8a36baafa6a85f2fd0f95b1367
icons/android-chrome-512x512.png,1742163336000,ecea49f2fa9a08b5245e9f8e6d0a45fd5388508fc280fad141e53d1e9acefff4
icons/Icon-maskable-512.png,1738903832255,e7983524dc70254adc61764657d7e03d19284de8da586b5818d737bc08c6d14e
icons/Icon-maskable-192.png,1738903832254,dd96c123fdf6817cdf7e63d9693bcc246bac2e3782a41a6952fa41c0617c5573
icons/Icon-512.png,1738903832254,7a31ce91e554f1941158ca46f31c7f3f2b7c8c129229ea74a8fae1affe335033
icons/Icon-192.png,1738903832254,d2e0131bb7851eb9d98f7885edb5ae4b4d6b7a6c7addf8a25b9b712b39274c0f
icons/Icon-192.png,1742163336000,6d7ee72aa1c5ac35e5dd1ab12f907f6d8cecce25ff518884cea0a275fb090167
canvaskit/skwasm_st.wasm,1738904552000,669c860c596b623d7c98a6b4c60d2bcadc92d13ee78b7e565612eb7d2b96b04c
canvaskit/skwasm_st.js.symbols,1738904552000,dbf1ecd2987907700e49fee8eef71967eaf756e205fb2e97cd9c4b239ab4c2e2
canvaskit/skwasm_st.js,1738904552000,5099d82713c753802530620e167e0f11fb72010175acb07527e54e55b725612d
Expand Down Expand Up @@ -52,17 +53,16 @@ assets/assets/fonts/Pretendard-ExtraLight.ttf,1741271571702,bf25b1053065297c0cac
assets/assets/fonts/Pretendard-ExtraBold.ttf,1741271571695,374f1cdec1c9872bfdabfc5049437dd6334dee93700538243ef573f3b735de04
assets/assets/fonts/Pretendard-Bold.ttf,1741271571690,2e40f7edb945eec3271f1e5cd938fe774adade44641e0715a89330354b8b5262
assets/assets/fonts/Pretendard-Black.ttf,1741271571685,d54873770d0faf69253bb90d4318993b837fd7b584833d375fb53fddf2182a57
assets/assets/characters/onboarding_character.svg,1741271571680,d7423b05fd5c5682f721ee5e366f0092ea8fd13f1794770c47b53c4f33bfd86c
version.json,1741607900550,3fe66f58c7b0080dde159d39cc063691b0918161056f5a917bf3094372849e2f
index.html,1741607900210,e6a4c3648fae56c90d8af60cad7f33c7ddbbbf0692bc549fd3b1a1b01b84f1e0
flutter_service_worker.js,1741607902208,304395399a0af87ad797407c05f35c59b04578f8a1fa9ca77c6cdcc449af8603
firebase-messaging-sw.js,1741607895287,eedb577a90ce796089ee56fbe936247b155b7de5f3ba19d4717b71b4bad8c426
assets/AssetManifest.bin,1741607900637,848d912e47b25284d97d790d3e271b0de0aa5d19e3efbb90e3f95567a858255b
assets/AssetManifest.json,1741607900637,aff3e6c632d817b41f7197c38d2adcb386ee097941919f4ec4ec9774038ceebf
assets/FontManifest.json,1741607900637,0c968932010df9e5202500a7acdd4f8448d421d4017ca6afaf4335c16dc951aa
flutter_bootstrap.js,1741607900206,d703da8e50a713f8a7aec30e94eaac31242943a0a9177cf5e0091f46adf47d01
assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1741607901627,53de5ef48304000a5bae3a08f9499510850cbb032372063e82f1f1dcd938f395
assets/AssetManifest.bin.json,1741607900637,f4c775243f2f51d0fddd7a5678c608288f7ad1985f861fcb331178b50ad031a3
assets/shaders/ink_sparkle.frag,1741607900734,80c6e65c75f1de434b1b22dba61e96ad82dba0f2fc5e8b3b59c2def46d794354
assets/fonts/MaterialIcons-Regular.otf,1741607901627,9fd6dfb402eb47d98919d5fc0b5ff7fdcca2d7e8c4b66fa69ac9cabcb6f18af7
assets/NOTICES,1741607900640,efb01c5cd600fe3ae72b5c7b44733ac570e80f528e4c1d207b16684e33e5f51d
version.json,1742196629388,3fe66f58c7b0080dde159d39cc063691b0918161056f5a917bf3094372849e2f
flutter_service_worker.js,1742196631024,702f2111014a58322d9348ae1347dc422ca892fb10869084a933b44abe544abd
flutter_bootstrap.js,1742196629054,4bf591df5ab527696b57c069974925265ec05303160fb0cf04391d21433af517
index.html,1742196629058,8e245a51242bf7295809eb2acfe4d385ac43314cda8f950a671efc732f2389dd
assets/AssetManifest.json,1742196629484,047af0ade8f084f8d59e40e9dd3c5a2d3e1ffa3de23d50f9d4c03c4ed3b77b09
assets/FontManifest.json,1742196629484,0c968932010df9e5202500a7acdd4f8448d421d4017ca6afaf4335c16dc951aa
favicon.ico,1742163336000,f9a33e18c8eda1a025b8bc80736ac4cb93ff348dc42f1dd19d34eb30080e4c73
assets/AssetManifest.bin.json,1742196629484,964cf7d6b415bb1842182a8a79ab9d021ad14962a7a139633bd47a1a872677c1
assets/AssetManifest.bin,1742196629484,010317c335c67cd05018616bd643931078fc91a96de7ed76e5544fe7ccdfb195
assets/shaders/ink_sparkle.frag,1742196629588,80c6e65c75f1de434b1b22dba61e96ad82dba0f2fc5e8b3b59c2def46d794354
assets/fonts/MaterialIcons-Regular.otf,1742196630435,ca9df6f14a20e3b4e1ae7b7857f56b0563ab90564b04633477e4242f948dce70
assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1742196630435,53de5ef48304000a5bae3a08f9499510850cbb032372063e82f1f1dcd938f395
assets/NOTICES,1742196629484,efb01c5cd600fe3ae72b5c7b44733ac570e80f528e4c1d207b16684e33e5f51d
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:firebase_messaging/firebase_messaging.dart';

Future<String> requestNotificationPermission() {
final settings = FirebaseMessaging.instance.requestPermission(
alert: true,
badge: true,
sound: true,
provisional: false,
announcement: false,
carPlay: false,
criticalAlert: false,
);
return settings.then((value) => value.authorizationStatus.toString());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'package:on_time_front/core/services/js_interop_service.dart';

Future<String> requestNotificationPermission() {
return JsInteropService.requestNotificationPermission();
}
2 changes: 2 additions & 0 deletions lib/core/services/notification_request_service/shared.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'notification_request_mobile_service.dart'
if (dart.library.html) 'notification_request_web_service.dart';
24 changes: 3 additions & 21 deletions lib/core/services/notification_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show kIsWeb;

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:on_time_front/core/services/js_interop_service.dart';
import 'package:on_time_front/core/services/notification_request_service/shared.dart';

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {}
Expand All @@ -21,7 +21,8 @@ class NotificationService {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

// Request permission
await _requestPermission();
final String authorizationStatus = await requestNotificationPermission();
print('Permission status: $authorizationStatus');

// Setup message handlers
await _setupMessageHandlers();
Expand All @@ -36,25 +37,6 @@ class NotificationService {
print('FCM Token: $token');
}

Future<void> _requestPermission() async {
if (kIsWeb) {
final permission = await JsInteropService.requestNotificationPermission();
print('Permission status: $permission');
} else {
final settings = await _messaging.requestPermission(
alert: true,
badge: true,
sound: true,
provisional: false,
announcement: false,
carPlay: false,
criticalAlert: false,
);

print('Permission status: ${settings.authorizationStatus}');
}
}

Future<void> setupFlutterNotifications() async {
if (_isFlutterLocalNotificationsInitialized) {
return;
Expand Down
7 changes: 4 additions & 3 deletions lib/data/models/sign_in_with_google_request_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ part 'sign_in_with_google_request_model.g.dart';

@JsonSerializable()
class SignInWithGoogleRequestModel {
final String accessToken;
final String idToken;

SignInWithGoogleRequestModel({
required this.accessToken,
required this.idToken,
});

Map<String, dynamic> toJson() {
return {
'accessToken': accessToken,
'idToken': idToken,
'refreshToken': '',
};
}
}
43 changes: 22 additions & 21 deletions lib/data/repositories/user_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ import 'package:rxdart/subjects.dart';
class UserRepositoryImpl implements UserRepository {
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
final TokenLocalDataSource _tokenLocalDataSource;
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'profile'],
forceCodeForRefreshToken: true,
);
late final _userStreamController = BehaviorSubject<UserEntity>.seeded(
const UserEntity.empty(),
);

@override
GoogleSignIn get googleSignIn => _googleSignIn;

UserRepositoryImpl(
this._authenticationRemoteDataSource, this._tokenLocalDataSource) {
_tokenLocalDataSource.authenticationStream.listen((state) {
Expand Down Expand Up @@ -70,29 +77,23 @@ class UserRepositoryImpl implements UserRepository {
}

@override
Future<void> signInWithGoogle() async {
final GoogleSignIn googleSignIn =
GoogleSignIn(scopes: ['email', 'profile']);
Future<void> signInWithGoogle(GoogleSignInAccount googleUser) async {
try {
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser != null) {
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final String? accessToken = googleAuth.accessToken;
if (accessToken != null) {
final signInWithGoogleRequestModel = SignInWithGoogleRequestModel(
accessToken: accessToken,
);
await _tokenLocalDataSource.deleteToken();
final result = await _authenticationRemoteDataSource
.signInWithGoogle(signInWithGoogleRequestModel);
await _tokenLocalDataSource.storeTokens(result.$2);
_userStreamController.add(result.$1);
} else {
throw Exception('Access Token is null');
}
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final String? idToken = googleAuth.idToken;
if (idToken != null) {
final signInWithGoogleRequestModel = SignInWithGoogleRequestModel(
idToken: idToken,
);
print(idToken);
await _tokenLocalDataSource.deleteToken();
final result = await _authenticationRemoteDataSource
.signInWithGoogle(signInWithGoogleRequestModel);
await _tokenLocalDataSource.storeTokens(result.$2);
_userStreamController.add(result.$1);
} else {
throw Exception('Google User is null');
throw Exception('Access Token is null');
}
} catch (e) {
debugPrint(e.toString());
Expand Down
5 changes: 4 additions & 1 deletion lib/domain/repositories/user_repository.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import 'package:google_sign_in/google_sign_in.dart';
import 'package:on_time_front/domain/entities/user_entity.dart';

abstract interface class UserRepository {
Stream<UserEntity> get userStream;

GoogleSignIn get googleSignIn;

Future<void> signUp(
{required String email, required String password, required String name});

Future<void> signIn({required String email, required String password});

Future<void> signOut();

Future<void> signInWithGoogle();
Future<void> signInWithGoogle(GoogleSignInAccount account);

Future<void> getUser();
}
1 change: 0 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:on_time_front/core/constants/environment_variable.dart';
import 'package:on_time_front/core/di/di_setup.dart';
import 'package:on_time_front/core/services/notification_service.dart';
import 'package:on_time_front/firebase_options.dart';
import 'package:on_time_front/presentation/app/screens/app.dart';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
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(
'assets/google_icon.svg',
semanticsLabel: 'Google Icon',
fit: BoxFit.contain,
);

@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');
}
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),
),
],
),
child: Padding(
padding: const EdgeInsets.all(9.0),
child: googleIconSvg,
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/widgets.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:google_sign_in_web/web_only.dart';
import 'package:on_time_front/core/di/di_setup.dart';
import 'package:on_time_front/domain/repositories/user_repository.dart';

class GoogleSignInButton extends StatefulWidget {
const GoogleSignInButton({super.key});

@override
State<GoogleSignInButton> createState() => _GoogleSignInButtonState();
}

class _GoogleSignInButtonState extends State<GoogleSignInButton> {
final authenticationRepository = getIt.get<UserRepository>();
@override
void initState() {
authenticationRepository.googleSignIn.onCurrentUserChanged
.listen((GoogleSignInAccount? account) {
if (account != null) {
getIt.get<UserRepository>().signInWithGoogle(account);
}
});
super.initState();
}

@override
Widget build(BuildContext context) {
return renderButton();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'unsupported.dart'
if (dart.library.html) 'google_sign_in_button_web.dart'
if (dart.library.io) 'google_sign_in_button_mobile.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/widgets.dart';

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

@override
Widget build(BuildContext context) {
return SizedBox.shrink();
}
}
Loading