Skip to content

Commit

Permalink
improved auto connect
Browse files Browse the repository at this point in the history
  • Loading branch information
hedihadi committed Nov 7, 2024
1 parent 51b342f commit 3926898
Show file tree
Hide file tree
Showing 18 changed files with 231 additions and 104 deletions.
28 changes: 28 additions & 0 deletions zal_app/lib/Functions/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ class ComputerAddress {
required this.name,
required this.ip,
});

Map<String, dynamic> toMap() {
return <String, dynamic>{
'name': name,
'ip': ip,
};
}

factory ComputerAddress.fromMap(Map<String, dynamic> map) {
return ComputerAddress(
name: map['name'] as String,
ip: map['ip'] as String,
);
}

String toJson() => json.encode(toMap());

factory ComputerAddress.fromJson(String source) => ComputerAddress.fromMap(json.decode(source) as Map<String, dynamic>);

@override
bool operator ==(covariant ComputerAddress other) {
if (identical(this, other)) return true;

return other.name == name && other.ip == ip;
}

@override
int get hashCode => name.hashCode ^ ip.hashCode;
}

class ConnectionEstablishment {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:zal/Functions/models.dart';
import 'package:zal/Screens/InitialConnectionScreen/Widgets/initial_connection_settings_screen.dart';
import 'package:zal/Screens/InitialConnectionScreen/initial_connection_screen_providers.dart';
import 'package:zal/Screens/MainScreen/SettingsScreen/settings_providers.dart';
import 'package:url_launcher/url_launcher.dart';

class ChooseComputerWidget extends ConsumerWidget {
const ChooseComputerWidget({super.key});
Expand Down Expand Up @@ -73,10 +74,9 @@ class ChooseComputerWidget extends ConsumerWidget {
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
ref.read(settingsProvider.notifier).updateSettings('address', computers[index].ip);
Navigator.pop(context);
},
child: const Text("Select"),
child: const Text("Connect"),
),
),
),
Expand All @@ -86,6 +86,19 @@ class ChooseComputerWidget extends ConsumerWidget {
);
},
),
const Divider(),
Wrap(
children: [
const Text("your phone must be connected to the same network as your PC"),
TextButton.icon(
onPressed: () {
launchUrl(Uri.parse("https://discord.gg/kfyZmqXjd6"), mode: LaunchMode.externalNonBrowserApplication);
},
label: const Text("Get help on Discord"),
icon: const Icon(FontAwesomeIcons.discord),
),
],
),
],
);
// return computers.when(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,119 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:sizer/sizer.dart';
import 'package:zal/Functions/models.dart';
import 'package:zal/Screens/ConnectedScreen/connected_screen.dart';
import 'package:zal/Screens/InitialConnectionScreen/Widgets/choose_computer_widget.dart';
import 'package:zal/Screens/InitialConnectionScreen/Widgets/initial_connection_settings_screen.dart';
import 'package:zal/Screens/InitialConnectionScreen/initial_connection_screen_providers.dart';
import 'package:zal/Screens/MainScreen/SettingsScreen/settings_providers.dart';
import 'package:zal/Screens/MainScreen/main_screen_providers.dart';
import 'package:url_launcher/url_launcher.dart';

class InitialConnectionScreen extends ConsumerWidget {
const InitialConnectionScreen({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final isConnected = ref.watch(isConnectedToServerProvider);
final settings = ref.watch(settingsProvider).valueOrNull;
final computers = ref.watch(loadedComputerAddressesProvider);
final isLoading = ref.watch(localcomputerAddressesProvider).isLoading;
ref.watch(socketStreamProvider);
final address = settings?['address'];
ref.read(socketProvider);
if (isConnected) return ConnectedScreen();

return Scaffold(
appBar: AppBar(),
body: Column(
children: [
const Spacer(),
if (address == null) const Text("You haven't connected to any PC before, connect to a PC first."),
if (address != null)
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 2.w),
child: Column(
children: [
const Spacer(),
Center(
child: Text("Connecting to $address"),
child: Text(
"Choose the PC you want to connect",
style: Theme.of(context).textTheme.titleMedium,
),
),
if (address != null) const Spacer(),
Center(
child: TextButton(
onPressed: () {
AlertDialog alert = AlertDialog(
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text("Cancel"))
],
content: SizedBox(width: 90.w, child: const ChooseComputerWidget()),
);

// show the dialog
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return alert;
if (ref.read(localcomputerAddressesProvider).error?.runtimeType == NetworkPrefixIsNull)
const Card(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text("we couldn't get the network prefix, please manually set it in Settings"),
)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
ref.invalidate(localcomputerAddressesProvider);
},
icon: const Icon(FontAwesomeIcons.arrowsRotate),
),
if (isLoading) const Center(child: CircularProgressIndicator()),
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const InitialConnectionSettingsScreen()));
},
icon: const Icon(FontAwesomeIcons.gear),
),
],
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: computers.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
computers[index].name,
style: Theme.of(context).textTheme.titleMedium,
),
Text("IP: ${computers[index].ip.replaceAll('http://', '')}"),
],
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
ref.read(socketProvider.notifier).connect(computers[index]);
},
child: const Text("Connect"),
),
),
),
],
),
),
);
},
child: const Text("Find your PC"),
),
),
SizedBox(height: 4.h),
if (address == null) const Spacer(),
],
const Spacer(),
const Divider(),
Wrap(
children: [
const Text("your phone must be connected to the same network as your PC"),
TextButton.icon(
onPressed: () {
launchUrl(Uri.parse("https://discord.gg/kfyZmqXjd6"), mode: LaunchMode.externalNonBrowserApplication);
},
label: const Text("Get help on Discord"),
icon: const Icon(FontAwesomeIcons.discord),
),
],
),
SizedBox(height: 3.h),
],
),
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:zal/Functions/models.dart';
import 'package:zal/Functions/utils.dart';
import 'package:zal/Screens/ConnectedScreen/connected_screen_providers.dart';
import 'package:zal/Screens/MainScreen/SettingsScreen/settings_providers.dart';
import 'package:http/http.dart' as http;
import 'package:zal/Screens/MainScreen/main_screen_providers.dart';

final isConnectedToServerProvider = StateProvider<bool>((ref) => false);
final loadedComputerAddressesProvider = StateProvider<List<ComputerAddress>>((ref) => []);
Expand All @@ -19,7 +21,10 @@ final networkPrefixProvider = FutureProvider<String?>((ref) async {

final localcomputerAddressesProvider = FutureProvider<List<ComputerAddress>?>((ref) async {
ref.invalidate(loadedComputerAddressesProvider);
final isConnected = ref.watch(isConnectedToServerProvider);
if (isConnected) return ref.read(loadedComputerAddressesProvider);
final settings = ref.watch(settingsProvider);
final ComputerAddress? address = settings.valueOrNull?['address'] == null ? null : ComputerAddress.fromJson(settings.valueOrNull?['address']);
final networkPrefix = ref.watch(networkPrefixProvider);
if (networkPrefix.isLoading || settings.isLoading) return null;
if (networkPrefix.valueOrNull == null) throw NetworkPrefixIsNull();
Expand All @@ -35,10 +40,11 @@ final localcomputerAddressesProvider = FutureProvider<List<ComputerAddress>?>((r
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
if (data['server'] == 'Zal') {
ref.read(loadedComputerAddressesProvider.notifier).state = [
...ref.read(loadedComputerAddressesProvider),
ComputerAddress(name: data['name'], ip: ip)
];
final computerAddress = ComputerAddress(name: data['name'], ip: ip);
ref.read(loadedComputerAddressesProvider.notifier).state = [...ref.read(loadedComputerAddressesProvider), computerAddress];
if (computerAddress.name == address?.name) {
ref.read(socketProvider.notifier).connect(computerAddress);
}
return;
}
}
Expand Down
22 changes: 13 additions & 9 deletions zal_app/lib/Screens/MainScreen/main_screen_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,27 @@ final isUserPremiumProvider = StateNotifierProvider<IsUserPremiumNotifier, bool>

final contextProvider = StateProvider<BuildContext?>((ref) => null);

final defaultComputerAddressProvider = StateProvider<String?>((ref) {
final settings = ref.watch(settingsProvider).valueOrNull;
final address = settings?['address'];
return address;
});

class SocketObjectNotifier extends AsyncNotifier<SocketObject?> {
ComputerAddress? currentAddress;
@override
Future<SocketObject?> build() async {
final address = ref.watch(defaultComputerAddressProvider);
if (address == null) return null;
return SocketObject(address, null, null);
return null;
}

connect(ComputerAddress address) {
if (currentAddress == address) return;
currentAddress = address;
ref.read(settingsProvider.notifier).updateSettings('address', address.toJson());

state = AsyncData(SocketObject(address.ip, null, null));
}

sendMessage(String key, dynamic value) {
state.valueOrNull?.socket.emit(key, value);
}

disconnect() {
currentAddress = null;
state.valueOrNull?.socket.dispose();
ref.invalidateSelf();
}
Expand All @@ -90,6 +92,8 @@ final socketStreamProvider = StreamProvider<SocketData>((ref) async* {
final socket = ref.watch(socketProvider).valueOrNull;
if (socket != null) {
socket.socket.onConnect((data) {
ref.read(isConnectedToServerProvider.notifier).state = true;

//showSnackbarLocal("Server Connected");
});
socket.socket.onDisconnect((data) {
Expand Down
2 changes: 1 addition & 1 deletion zal_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 2.0.0+29
version: 2.0.1+30

environment:
sdk: ">=3.2.0 <4.0.0"
Expand Down
Binary file modified zal_program/.vs/Zal/v17/.suo
Binary file not shown.
Loading

0 comments on commit 3926898

Please sign in to comment.