diff --git a/lib/chats.dart b/lib/chats.dart new file mode 100644 index 0000000..3d8cbdb --- /dev/null +++ b/lib/chats.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:matrix/matrix.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:zenith/zenith_client_provider.dart'; + +class ChatsPage extends StatefulWidget { + const ChatsPage({super.key}); + + @override + State createState() => _ChatsPageState(); +} + +class _ChatsPageState extends State { + final serverController = TextEditingController(); + final usernameController = TextEditingController(); + final passwordController = TextEditingController(); + late Client client; + bool roomsLoading = false; + + @override + void initState() { + super.initState(); + client = Provider.of(context, listen: false).client; + client.onRoomState.stream.listen((event) { + print(event.type); + }); + } + + void sendMessage() {} + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text("Zenith"), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Center( + child: roomsLoading + ? const CircularProgressIndicator() + : Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [Text("${client.rooms.length} Rooms.")], + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: sendMessage, + tooltip: 'Send message', + child: const Icon(Icons.send), + ), + ); + } +} diff --git a/lib/login.dart b/lib/login.dart index 2f99d67..f8e28d9 100644 --- a/lib/login.dart +++ b/lib/login.dart @@ -1,5 +1,9 @@ import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:zenith/chats.dart'; +import 'package:zenith/zenith_client_provider.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -14,24 +18,20 @@ class _LoginPageState extends State { final passwordController = TextEditingController(); void connectMatrix() async { - debugPrint("Making the client..."); - final client = Client("zenith"); - client.onLoginStateChanged.stream.listen((event) { - debugPrint("LoginState=${event.toString()}"); - }); + final provider = Provider.of(context, listen: false); + await provider.initialize(serverController.text, usernameController.text, + passwordController.text); - debugPrint("Checking the homeserver..."); - await client.checkHomeserver(Uri.parse(serverController.text)); + final prefs = await SharedPreferences.getInstance(); + prefs.setString("homeserver", serverController.text); + prefs.setString("username", usernameController.text); + prefs.setString("password", passwordController.text); - debugPrint("Logging in..."); - await client.login(LoginType.mLoginPassword, - identifier: AuthenticationUserIdentifier(user: usernameController.text), - password: passwordController.text); - - for (var room in client.rooms) { - debugPrint( - "Room ID: ${room.id}, Room Name: ${room.getLocalizedDisplayname()}"); - } + if (!mounted) return; + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => const ChatsPage()), + (route) => false); } @override diff --git a/lib/main.dart b/lib/main.dart index afb4f81..7ff4240 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:zenith/chats.dart'; import 'package:zenith/login.dart'; +import 'package:provider/provider.dart'; +import 'package:zenith/zenith_client_provider.dart'; void main() { runApp(const MyApp()); @@ -10,13 +15,16 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Zenith', - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, + return ChangeNotifierProvider( + create: (context) => ZenithClientProvider(), + child: MaterialApp( + title: 'Zenith', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const MyHomePage(), ), - home: const MyHomePage(), ); } } @@ -29,13 +37,36 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { + bool savedCreds = false; + + void getCreds() async { + final prefs = await SharedPreferences.getInstance(); + final homeserver = prefs.getString("homeserver"); + final username = prefs.getString("username"); + final password = prefs.getString("password"); + + if (homeserver == null || username == null || password == null) return; + setState(() { + savedCreds = true; + }); + + if (!mounted) return; + final provider = Provider.of(context, listen: false); + await provider.initialize(homeserver, username, password); + } + @override void initState() { super.initState(); + getCreds(); } @override Widget build(BuildContext context) { - return const LoginPage(); + if (!savedCreds) { + return const LoginPage(); + } else { + return const ChatsPage(); + } } } diff --git a/lib/zenith_client_provider.dart b/lib/zenith_client_provider.dart new file mode 100644 index 0000000..f598558 --- /dev/null +++ b/lib/zenith_client_provider.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:matrix/matrix.dart'; + +class ZenithClientProvider extends ChangeNotifier { + late Client _client; + + Client get client => _client; + + void setClient(Client newClient) { + _client = newClient; + notifyListeners(); + } + + Future initialize( + String homeserver, String username, String password) async { + _client = Client("zenith"); + print("Checking homeserver..."); + await client.checkHomeserver(Uri.parse(homeserver)); + print("Logging in..."); + await client.login(LoginType.mLoginPassword, + identifier: AuthenticationUserIdentifier(user: username), + password: password); + notifyListeners(); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..724bb2a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index f931f87..1928b71 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" flutter: dependency: "direct main" description: flutter @@ -171,6 +179,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" hive: dependency: transitive description: @@ -315,6 +328,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" petitparser: dependency: transitive description: @@ -323,6 +360,22 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + url: "https://pub.dev" + source: hosted + version: "2.1.7" pointycastle: dependency: transitive description: @@ -355,6 +408,62 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.2" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + url: "https://pub.dev" + source: hosted + version: "2.3.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + url: "https://pub.dev" + source: hosted + version: "2.3.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + url: "https://pub.dev" + source: hosted + version: "2.3.2" sky_engine: dependency: transitive description: flutter @@ -472,6 +581,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + win32: + dependency: transitive + description: + name: win32 + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 + url: "https://pub.dev" + source: hosted + version: "5.1.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + url: "https://pub.dev" + source: hosted + version: "1.0.3" xml: dependency: transitive description: @@ -482,4 +607,4 @@ packages: version: "6.3.0" sdks: dart: ">=3.1.5 <4.0.0" - flutter: ">=1.20.0" + flutter: ">=3.7.0" diff --git a/pubspec.yaml b/pubspec.yaml index 343e4b9..96cd86c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,6 +39,7 @@ dependencies: flutter_olm: ^1.4.1 flutter_openssl_crypto: ^0.3.0 provider: ^6.1.1 + shared_preferences: ^2.2.2 dev_dependencies: flutter_test: