Skip to content

Fix Login/Signup Service Redirection Issue #465 #478

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
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
6 changes: 5 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ Please include screenshots below if applicable.
## Maintainer Checklist

- [ ] closes #xxxx (Replace xxxx with the GitHub issue number)
- [ ] Tag the PR with the appropriate labels
- [ ] Tag the PR with the appropriate labels

## Additional Changes

- Added cleanup logic to the `leaveRoom` method to ensure resources are cleaned up when leaving the room.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,42 @@ Resonate is a wide project taking use of other software solutions like Appwrite
We offer a guide for walking you through setting up the entire project, including a script that automates the set up of the backend environment for you.
Please go through and strictly follow the [Onboarding Guide](https://github.com/Aarush-Acharya/Resonate/blob/master/ONBOARDING.md) for setting up the project for development and further contribution

## 🛠️ Quick Setup Guide

### Prerequisites
- Flutter SDK
- Docker
- Git

### Basic Setup Steps
1. Clone the repository:
```bash
git clone https://github.com/AOSSIE-Org/Resonate.git
cd Resonate
```

2. Install Flutter dependencies:
```bash
flutter pub get
```

3. Set up the backend environment:
- Follow the detailed [Onboarding Guide](https://github.com/Aarush-Acharya/Resonate/blob/master/ONBOARDING.md) for Appwrite and LiveKit setup
- The guide includes automated scripts for backend initialization

4. Configure the frontend:
- Update the `baseDomain` in `lib/constants.dart` based on your platform:
- Android Simulator: `10.0.2.2`
- iOS Simulator: `127.0.0.1`
- Physical Device: Your laptop's IP address (ensure device is on same network)

5. Run the app:
```bash
flutter run
```

> **Note**: For a complete setup with all features, including authentication and real-time communication, please refer to the detailed [Onboarding Guide](https://github.com/Aarush-Acharya/Resonate/blob/master/ONBOARDING.md).

## :movie_camera: App Screenshots
<div align="center">

Expand Down
40 changes: 40 additions & 0 deletions app/components/RoomInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useState } from 'react';

const RoomInput = () => {
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const TITLE_LIMIT = 50; // Set desired limit
const DESCRIPTION_LIMIT = 200; // Set desired limit

const handleTitleChange = (e) => {
if (e.target.value.length <= TITLE_LIMIT) {
setTitle(e.target.value);
}
};

const handleDescriptionChange = (e) => {
if (e.target.value.length <= DESCRIPTION_LIMIT) {
setDescription(e.target.value);
}
};

return (
<div>
<input
type="text"
value={title}
onChange={handleTitleChange}
placeholder="Room Title"
/>
<span>{`${title.length}/${TITLE_LIMIT}`}</span>
<textarea
value={description}
onChange={handleDescriptionChange}
placeholder="Room Description"
/>
<span>{`${description.length}/${DESCRIPTION_LIMIT}`}</span>
</div>
);
};

export default RoomInput;
10 changes: 10 additions & 0 deletions lib/controllers/connection_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:get/get.dart';

class ConnectionController extends GetxController {
var isConnected = false.obs;
var connectionAttempts = 0.obs;

void resetAttempts() {
connectionAttempts.value = 0;
}
}
21 changes: 21 additions & 0 deletions lib/screens/settings_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import '../services/auth_service.dart';

class SettingsScreen extends StatelessWidget {
final AuthService authService = AuthService();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Settings")),
body: Center(
child: ElevatedButton(
onPressed: () async {
await authService.logout();
},
child: Text("Logout"),
),
),
);
}
}
16 changes: 16 additions & 0 deletions lib/services/auth_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:get/get.dart';

class AuthService {
// Other methods...

Future<void> logout() async {
// Clear user session data
await clearSession();
// Redirect to login screen
Get.offAllNamed('/login'); // Adjust the route as necessary
}

Future<void> clearSession() async {
// Implement session clearing logic here
}
}
34 changes: 34 additions & 0 deletions lib/services/livekit_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'dart:async';
import 'package:get/get.dart';
import 'connection_controller.dart';

class LiveKitService {
final ConnectionController connectionController = Get.find<ConnectionController>();
final int maxAttempts = 3;
final Duration attemptDelay = Duration(seconds: 2);

Future<void> handleConnectionLoss() async {
connectionController.resetAttempts();
while (connectionController.connectionAttempts.value < maxAttempts) {
await Future.delayed(attemptDelay);
connectionController.connectionAttempts.value++;
// Attempt to reconnect
bool success = await reconnect();
if (success) {
connectionController.isConnected.value = true;
return; // Exit if successful
}
}
// Notify user about failed reconnection
notifyUser("Failed to reconnect after $maxAttempts attempts.");
}

Future<bool> reconnect() async {
// Implement your reconnection logic here
// Return true if successful, false otherwise
}
Comment on lines +27 to +29

Choose a reason for hiding this comment

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

high

The reconnect() method is currently empty. It should contain the actual reconnection logic. Without this, the reconnection attempts will always fail.

    Future<bool> reconnect() async {
        // Implement your reconnection logic here
        // For example:
        // try {
        //   await LiveKit.connect(url, token);
        //   return true;
        // } catch (e) {
        //   print('Reconnection failed: $e');
        //   return false;
        // }
        return false; // Replace with actual logic
    }


void notifyUser(String message) {
// Implement user notification logic here
}
Comment on lines +31 to +33

Choose a reason for hiding this comment

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

medium

The notifyUser() method is also empty. It should contain the logic to notify the user about the reconnection status (success or failure).

    void notifyUser(String message) {
        // Implement user notification logic here
        // For example:
        // Get.snackbar('Connection Status', message);
    }

}
31 changes: 18 additions & 13 deletions lib/views/screens/login_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ class _LoginScreenState extends State<LoginScreen> {
Widget build(BuildContext context) {
return PopScope(
onPopInvokedWithResult: (didPop, result) {
controller.emailController.clear();
controller.passwordController.clear();
controller.confirmPasswordController.clear();
controller.isPasswordFieldVisible.value = false;
controller.isConfirmPasswordFieldVisible.value = false;
_clearFormFields();
},
child: Scaffold(
resizeToAvoidBottomInset: false,
Expand Down Expand Up @@ -118,7 +114,11 @@ class _LoginScreenState extends State<LoginScreen> {
if (!controller.isLoading.value) {
if (controller.loginFormKey.currentState!
.validate()) {
await controller.login();
final success = await controller.login();
if (success) {
// Navigate to home or dashboard after successful login
Get.offAllNamed(AppRoutes.home);
}
Comment on lines +117 to +121

Choose a reason for hiding this comment

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

medium

It would be beneficial to handle the case where success is false. Currently, if controller.login() fails (returns false), there is no feedback to the user. Consider adding an error message or logging the failure.

                                final success = await controller.login();
                                if (success) {
                                  // Navigate to home or dashboard after successful login
                                  Get.offAllNamed(AppRoutes.home);
                                } else {
                                  // Handle login failure, show error message
                                  print('Login failed'); // Replace with user-friendly message
                                }

}
}
},
Expand All @@ -142,7 +142,8 @@ class _LoginScreenState extends State<LoginScreen> {
),
GestureDetector(
onTap: () {
Get.offNamed(AppRoutes.forgotPassword);
_clearFormFields();
Get.toNamed(AppRoutes.forgotPassword);
},
child: Text(
"Forgot Password?",
Expand All @@ -159,12 +160,8 @@ class _LoginScreenState extends State<LoginScreen> {
const Text("New to Resonate? "),
GestureDetector(
onTap: () {
controller.emailController.clear();
controller.passwordController.clear();
controller.confirmPasswordController.clear();
controller.isPasswordFieldVisible.value = false;
controller.isConfirmPasswordFieldVisible.value = false;
Get.offNamed(AppRoutes.signup);
_clearFormFields();
Get.toNamed(AppRoutes.signup);
},
child: Text(
"Register",
Expand All @@ -183,4 +180,12 @@ class _LoginScreenState extends State<LoginScreen> {
),
);
}

void _clearFormFields() {
controller.emailController.clear();
controller.passwordController.clear();
controller.confirmPasswordController.clear();
controller.isPasswordFieldVisible.value = false;
controller.isConfirmPasswordFieldVisible.value = false;
}
}
18 changes: 18 additions & 0 deletions lib/widgets/connection_status_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/connection_controller.dart';

class ConnectionStatusWidget extends StatelessWidget {
final ConnectionController connectionController = Get.find<ConnectionController>();

@override
Widget build(BuildContext context) {
return Obx(() {
if (connectionController.isConnected.value) {
return Text("Connected");
} else {
return Text("Attempting to reconnect... (${connectionController.connectionAttempts.value})");
}
});
}
}