Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue - 275 (Meaningful Documentation) #286

Closed
53 changes: 52 additions & 1 deletion lib/controllers/auth_state_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ class AuthStateController extends GetxController {
late bool? isEmailVerified;
late User appwriteUser;

// initializes FlutterLocalNotifications Plugin provides cross-platform to display local notifications.
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

/*
- Sets up Android notification settings.
- Registers callback to handle Notification taps(onDidRecieveNotificationResponse)
- Enables overall notification capability.
*/
Comment on lines +39 to +43

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Dart documentation must be written using ///. This practice ensures that contributors can quickly understand the functionality of a function by hovering over it.

Future<void> initializeLocalNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('ic_launcher');
Expand All @@ -47,11 +53,24 @@ class AuthStateController extends GetxController {
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse);
}

/*Code Explaination of onDidReceiveNotificationResponse.
The below method handles the logic of tapping on a notification
1.Extract the discussion name from the notification payload.
2.Fetch the index of the discussion that is obtained after tapping on notification.
3.Lookup the matching discussion in the controller's list.
4.Make the ScrollController to get initialized to that offset.
5.Update tab Controller to switch to discussions tab.
6.Navigate user to the tabs screen.
*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned


void onDidReceiveNotificationResponse(
NotificationResponse notificationResponse) async {
String name = notificationResponse.payload!;
String name = notificationResponse
.payload!; //fetching the payload(custom key value pairs).

DiscussionsController discussionsController =
Get.find<DiscussionsController>();

int index = discussionsController.discussions
.indexWhere((discussion) => discussion.data["name"] == name);

Expand Down Expand Up @@ -119,6 +138,11 @@ class AuthStateController extends GetxController {
}
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

In the below method,
it Fetches and sets the user Profile info from Appwrite ,
and later updates the widgets.
*/
Future<void> setUserProfileData() async {
isInitializing.value = true;
try {
Expand Down Expand Up @@ -146,12 +170,27 @@ class AuthStateController extends GetxController {
}
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

In this below method (getAppwriteToken)
1.Call createJWT() on the account object
2.This returns a JWT class containing the signed token.
3.We return just the raw JWT string portion.
*/
Future<String> getAppwriteToken() async {
Jwt authToken = await account.createJWT();
log(authToken.toString());
return authToken.jwt;
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

In the below method(isUserLoggedIn)
- all we are trying to know is whether the userProfile is successfully setup or not.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and if the user is logged in or not, this goal is not highlighted make it more clear

- If yes then route the ui to tabView.
- If no then route the ui to onBoarding.
- If error, check if its a first launch
- On first launch, show landing page.
- Otherwise redirect to login screen.
*/
Future<void> isUserLoggedIn() async {
try {
await setUserProfileData();
Expand Down Expand Up @@ -195,6 +234,16 @@ class AuthStateController extends GetxController {
});
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

1. Get the current FCM token for the user's device.
2. Fetch the list of subscribed Discussion from appwrite collection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this,
2. Fetch the List of subscriptions made by this user
3. Loop through the subscriptions
4. Removing the FCM token of this device from the list of FCM tokens of each subscription
5. A FCM token in the list of FCM tokens of a subscription created by this user represents a device to which notification is to be sent on events related to the discussion subscription was made to as the user can login from many devices and if user is logged in through 3 different devices all of them needs to be sent notifications

3. Loop through subscribed discussion.
4. Get the list of tokens and remove current user's token.
5. Update the discusion.

Result: This keeps each discussion's tokens list uptodate as user
subscribe/unsubscribe over time.
*/
Future<void> removeRegistrationTokenfromSubscribedDiscussions() async {
final fcmToken = await messaging.getToken();
List<Document> subscribedDiscussions = await databases.listDocuments(
Expand Down Expand Up @@ -232,6 +281,8 @@ class AuthStateController extends GetxController {
await isUserLoggedIn();
}

//Displays dialog box for confirming the logout decision of user.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

//Then it performs the corresponding task.
Future<void> logout() async {
Get.defaultDialog(
title: "Are you sure?",
Expand Down
11 changes: 10 additions & 1 deletion lib/controllers/authentication_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:resonate/views/widgets/snackbar.dart';
class AuthenticationController extends GetxController {
var isPasswordFieldVisible = false.obs;
var isLoading = false.obs;

TextEditingController emailController = TextEditingController(text: "");
TextEditingController passwordController = TextEditingController(text: "");
TextEditingController confirmPasswordController =
Expand All @@ -19,6 +20,7 @@ class AuthenticationController extends GetxController {
var loginFormKey;
var registrationFormKey;

//Login the user using email and password.
Future<void> login() async {
if (!loginFormKey.currentState!.validate()) {
return;
Expand All @@ -30,7 +32,8 @@ class AuthenticationController extends GetxController {
} on AppwriteException catch (e) {
log(e.toString());
if (e.type == 'user_invalid_credentials') {
customSnackbar('Try Again!', "Incorrect Email Or Password", MessageType.error);
customSnackbar(
'Try Again!', "Incorrect Email Or Password", MessageType.error);
}
} catch (e) {
log(e.toString());
Expand All @@ -39,6 +42,10 @@ class AuthenticationController extends GetxController {
}
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

This method(signup) helps to sign the user through
email,password
*/
Future<bool> signup() async {
try {
isLoading.value = true;
Expand All @@ -57,6 +64,7 @@ class AuthenticationController extends GetxController {
}
}

//Sign in with Google .
Future<void> loginWithGoogle() async {
try {
await authStateController.loginWithGoogle();
Expand All @@ -65,6 +73,7 @@ class AuthenticationController extends GetxController {
}
}

//Sign in with Github.
Future<void> loginWithGithub() async {
try {
await authStateController.loginWithGithub();
Expand Down
8 changes: 8 additions & 0 deletions lib/controllers/discussions_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,28 @@ class DiscussionsController extends GetxController {
final Databases databases = AppwriteService.getDatabases();
TextEditingController dateTimeController = TextEditingController(text: "");
AuthStateController authStateController = Get.find<AuthStateController>();

final CreateRoomController createRoomController =
Get.find<CreateRoomController>();

Rx<ScrollController> discussionScrollController = ScrollController().obs;
final TabViewController controller = Get.find<TabViewController>();

final ThemeController themeController = Get.find<ThemeController>();
final RoomsController roomsController = Get.find<RoomsController>();

FirebaseMessaging messaging = FirebaseMessaging.instance;

late List<Document> discussions;
late String scheduledDateTime;
late Document currentUserDoc;
late Duration localTimeZoneOffset;
late String localTimeZoneName;
late bool isOffsetNegetive;

Rx<bool> isLoading = false.obs;
late DateTime currentTimeInstance;

final Map<String, String> monthMap = {
"1": "Jan",
"2": "Feb",
Expand All @@ -45,6 +52,7 @@ class DiscussionsController extends GetxController {
"11": "Nov",
"12": "Dec",
};

@override
void onInit() async {
super.onInit();
Expand Down
26 changes: 25 additions & 1 deletion lib/controllers/email_verify_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class EmailVerifyController extends GetxController {
var isVerifying = false.obs;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not convert these into actual type -> RxBool

var isUpdateAllowed = true.obs;
var signupisallowed = true.obs;
var clearTextField=false.obs;
var clearTextField = false.obs;

AuthStateController authStateController = Get.find<AuthStateController>();
AuthenticationController authController =
Get.find<AuthenticationController>();
Expand All @@ -39,20 +40,31 @@ class EmailVerifyController extends GetxController {
databases = Databases(authStateController.client);
}

//This method provides the service of sending OTP to user

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

//by leveraging the AppWrite functions.
Future<bool> sendOTP() async {
//sets the loading state to indicate ongoing process.
authController.isLoading.value = true;

//Generates OTP by appending randomNumber with email.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after //

var otpID = randomNumeric(10).toString() + authStateController.email!;

// Appwrite does not accept @ in document ID's
otpID = otpID.split("@")[0];

var sendOtpData = {
"email": authStateController.email,
"otpID": otpID.toString()
};

//updates the user's document in Appwrite.
await authStateController.account
.updatePrefs(prefs: {"otp_ID": otpID, "isUserProfileComplete": true});

//Encodes the data to be sent to the function into a json string.
var data = json.encode(sendOtpData);

//Triggers the Appwrite Function responsible for sending OTP emails.
var res = await functions.createExecution(
functionId: sendOtpFunctionID, data: data.toString());

Expand All @@ -75,6 +87,15 @@ class EmailVerifyController extends GetxController {
return true;
}

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

This below method helps to verify the user entered otp

Purpose of imp variables used in below code:
- otpId =>Retrieves the otp from user's document, representing the actual OTP.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otpId: the ID of the otp sent, which will help fetch the actual otp from server side.

prefs: Fetch the user account prefs to get the otpId from it, the otpID gets updated into user account prefs when an otp is sent to the user. It is the Id corresponding to the otp sent to the user

verificationId: After comparison between OTP sent and user entered OTP the server side updates the status of the verification in the verification document (each verification is represented by a document in the verification collection ), status is then used to check if the verification was successful or not

- userOTP => The user entered OTP.
- verificationID => Based on the comparison , the function will determine whether user
entered the correct OTP.
*/
Future<void> verifyOTP(String userOTP) async {
verificationID = randomNumeric(10).toString() + authStateController.email!;
verificationID = verificationID.split("@")[0];
Expand All @@ -90,6 +111,7 @@ class EmailVerifyController extends GetxController {
functionId: verifyOtpFunctionID, data: data.toString());
}

//Provides the verficiation Status of OTP entered by user.
Future<String> checkVerificationStatus() async {
final document = await databases.getDocument(
databaseId: emailVerificationDatabaseID,
Expand All @@ -100,6 +122,7 @@ class EmailVerifyController extends GetxController {
return isVerified;
}

//This function makes the user Profile set Verified.
Future<void> setVerified() async {
var verifyUserData = {
"userID": authStateController.uid,
Expand All @@ -109,6 +132,7 @@ class EmailVerifyController extends GetxController {
functionId: verifyUserFunctionID, data: verifyData.toString());
}

//Helps to update Email a creates a cloud function for it.
Future<void> updateEmail() async {
var updateEmailData = json.encode({
"User_ID": authStateController.uid,
Expand Down
46 changes: 31 additions & 15 deletions lib/controllers/livekit_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,30 @@ import 'package:livekit_client/livekit_client.dart';
import 'package:resonate/controllers/pair_chat_controller.dart';
import 'package:resonate/controllers/single_room_controller.dart';

class LiveKitController extends GetxController{
class LiveKitController extends GetxController {
late final Room liveKitRoom;
late final EventsListener<RoomEvent> listener;
final String liveKitUri;
final String roomToken;

LiveKitController({required this.liveKitUri, required this.roomToken});

/*
- In onInit() method, we try to create a new room and join it ,through roomtoken & liveKitURI.
- Setting up necessary listeners .
*/
@override
void onInit() async{
void onInit() async {
await joinLiveKitRoom(liveKitUri: liveKitUri, roomToken: roomToken);
liveKitRoom.addListener(onRoomDidUpdate);
setUpListeners();
super.onInit();
}

/*
In the onClose method ,all the resources that were allocated before are released
to prevent resource exploitation and avoid memory leaks.
*/
@override
void onClose() async {
(() async {
Expand All @@ -31,10 +39,10 @@ class LiveKitController extends GetxController{
super.onClose();
}

Future<void> joinLiveKitRoom({required String liveKitUri, required String roomToken}) async {
Future<void> joinLiveKitRoom(
{required String liveKitUri, required String roomToken}) async {
//
try {

//create new room
liveKitRoom = Room();

Expand All @@ -53,7 +61,6 @@ class LiveKitController extends GetxController{
),
),
);

} catch (error) {
log('Could not connect $error');
}
Expand All @@ -63,23 +70,32 @@ class LiveKitController extends GetxController{
//Callback which will be called on room update
}

/*
- This below method's purpose is to set up event listeners to handle specific
events related to rooms, disconnections and recording status changes.
*/
void setUpListeners() => listener
..on<RoomDisconnectedEvent>((event) async {
if (event.reason != null) {
log('Room disconnected: reason => ${event.reason}');
}
WidgetsBindingCompatible.instance
?.addPostFrameCallback((timeStamp) {
if (Get.isRegistered<SingleRoomController>()){
Get.find<SingleRoomController>().leaveRoom();
}
else if (Get.isRegistered<PairChatController>()){
Get.find<PairChatController>().endChat();
}

/*
Schedules a callback to run after the current frame completes.
- Checks if Registered Controllers are :
1.If SingleRoomController is registered , calls [leaveRoom()] to initate proper
room clean up.
2.If PairChatController is registered, calls [endChat()] to handle chat termination.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DartDocs, as mentioned

*/
WidgetsBindingCompatible.instance?.addPostFrameCallback((timeStamp) {
if (Get.isRegistered<SingleRoomController>()) {
Get.find<SingleRoomController>().leaveRoom();
} else if (Get.isRegistered<PairChatController>()) {
Get.find<PairChatController>().endChat();
}
});
})
..on<RoomRecordingStatusChanged>((event) {
//context.showRecordingStatusChangedDialog(event.activeRecording);
});

}
}
Loading