Compare commits
28
Commits
799c15321b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11de9ccfe8 | ||
|
|
128a1bf35f | ||
|
|
a552c30ba0 | ||
|
|
2039b4e90d | ||
|
|
1aa73bbd7e | ||
|
|
6ca8f646b2 | ||
|
|
a40dd74b96 | ||
|
|
10b84d1521 | ||
|
|
8ca788ccdd | ||
|
|
7c1e18c4e8 | ||
|
|
76411aa827 | ||
|
|
27b7f79d74 | ||
|
|
f229c0371b | ||
|
|
1cd8ba41ae | ||
|
|
3728172844 | ||
|
|
ea7587fe2d | ||
|
|
1376580e7e | ||
|
|
5fbc8bee42 | ||
|
|
9c93ea1008 | ||
|
|
e478552587 | ||
|
|
5c4526f1fc | ||
|
|
302f46804e | ||
|
|
071df18b81 | ||
|
|
c5ae0f0e85 | ||
|
|
705aeb568f | ||
|
|
3352939009 | ||
|
|
a6306ceddc | ||
|
|
112fe960be |
Vendored
+25
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "zenith",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"program": "${workspaceFolder}/lib/main.dart",
|
||||||
|
"flutterMode": "debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zenith (profile mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "profile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zenith (release mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -23,6 +23,8 @@ linter:
|
|||||||
rules:
|
rules:
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
curly_braces_in_flow_control_structures: false
|
||||||
|
avoid_print: false
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
# Additional information about this file can be found at
|
||||||
# https://dart.dev/guides/language/analysis-options
|
# https://dart.dev/guides/language/analysis-options
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="zenith"
|
android:label="zenith"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
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<ChatsPage> createState() => _ChatsPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ChatsPageState extends State<ChatsPage> {
|
|
||||||
final serverController = TextEditingController();
|
|
||||||
final usernameController = TextEditingController();
|
|
||||||
final passwordController = TextEditingController();
|
|
||||||
late Client client;
|
|
||||||
bool roomsLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
client = Provider.of<ZenithClientProvider>(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),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+51
-10
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:zenith/chats.dart';
|
import 'package:zenith/rooms.dart';
|
||||||
import 'package:zenith/zenith_client_provider.dart';
|
import 'package:zenith/zenith_client_provider.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
@@ -16,11 +16,42 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
final serverController = TextEditingController();
|
final serverController = TextEditingController();
|
||||||
final usernameController = TextEditingController();
|
final usernameController = TextEditingController();
|
||||||
final passwordController = TextEditingController();
|
final passwordController = TextEditingController();
|
||||||
|
bool loggingIn = false;
|
||||||
|
String failedMessage = '';
|
||||||
|
|
||||||
|
void login() async {
|
||||||
|
setState(() {
|
||||||
|
loggingIn = true;
|
||||||
|
});
|
||||||
|
|
||||||
void connectMatrix() async {
|
|
||||||
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
||||||
await provider.initialize(serverController.text, usernameController.text,
|
|
||||||
passwordController.text);
|
try {
|
||||||
|
await provider.client.checkHomeserver(Uri.parse(serverController.text));
|
||||||
|
await provider.client.login(
|
||||||
|
LoginType.mLoginPassword,
|
||||||
|
password: passwordController.text,
|
||||||
|
identifier: AuthenticationUserIdentifier(user: usernameController.text),
|
||||||
|
refreshToken: true,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
print(error);
|
||||||
|
setState(() {
|
||||||
|
failedMessage = error.toString();
|
||||||
|
loggingIn = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
Future.delayed(const Duration(seconds: 10), () {
|
||||||
|
setState(() {
|
||||||
|
failedMessage = '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
loggingIn = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
prefs.setString("homeserver", serverController.text);
|
prefs.setString("homeserver", serverController.text);
|
||||||
@@ -30,7 +61,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pushAndRemoveUntil(
|
Navigator.pushAndRemoveUntil(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const ChatsPage()),
|
MaterialPageRoute(builder: (context) => const RoomsPage()),
|
||||||
(route) => false);
|
(route) => false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,41 +72,51 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Consumer<ZenithClientProvider>(
|
||||||
|
builder: (context, provider, child) => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
title: const Text("Login"),
|
title: const Text("Login"),
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: serverController,
|
controller: serverController,
|
||||||
|
autocorrect: false,
|
||||||
|
textCapitalization: TextCapitalization.none,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Server', hintText: 'https://matrix.org'),
|
labelText: 'Server', hintText: 'https://matrix.org'),
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: usernameController,
|
controller: usernameController,
|
||||||
|
autocorrect: false,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Username', hintText: 'john'),
|
labelText: 'Username', hintText: 'john'),
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: passwordController,
|
controller: passwordController,
|
||||||
|
autocorrect: false,
|
||||||
decoration: const InputDecoration(labelText: 'Password'),
|
decoration: const InputDecoration(labelText: 'Password'),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
|
onFieldSubmitted: (value) => login(),
|
||||||
),
|
),
|
||||||
|
Text(failedMessage,
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: connectMatrix,
|
onPressed: loggingIn ? null : login,
|
||||||
tooltip: 'Log in',
|
tooltip: 'Log in',
|
||||||
child: const Icon(Icons.login),
|
child: loggingIn
|
||||||
),
|
? const CircularProgressIndicator()
|
||||||
|
: const Icon(Icons.login),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-10
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:zenith/chats.dart';
|
import 'package:zenith/rooms.dart';
|
||||||
import 'package:zenith/login.dart';
|
import 'package:zenith/login.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:zenith/zenith_client_provider.dart';
|
import 'package:zenith/zenith_client_provider.dart';
|
||||||
@@ -37,7 +37,8 @@ class MyHomePage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
bool savedCreds = false;
|
bool showRooms = false;
|
||||||
|
String errorMessage = "";
|
||||||
|
|
||||||
void getCreds() async {
|
void getCreds() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
@@ -46,13 +47,25 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
final password = prefs.getString("password");
|
final password = prefs.getString("password");
|
||||||
|
|
||||||
if (homeserver == null || username == null || password == null) return;
|
if (homeserver == null || username == null || password == null) return;
|
||||||
setState(() {
|
|
||||||
savedCreds = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
||||||
await provider.initialize(homeserver, username, password);
|
setState(() {
|
||||||
|
showRooms = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await provider.client.checkHomeserver(Uri.parse(homeserver));
|
||||||
|
if (!provider.client.isLogged())
|
||||||
|
await provider.client.login(LoginType.mLoginPassword,
|
||||||
|
password: password,
|
||||||
|
identifier: AuthenticationUserIdentifier(user: username));
|
||||||
|
} catch (error) {
|
||||||
|
print(error);
|
||||||
|
setState(() {
|
||||||
|
errorMessage = error.toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -63,10 +76,22 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (!savedCreds) {
|
if (errorMessage.isNotEmpty)
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
errorMessage = "";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text("Clear")),
|
||||||
|
ErrorWidget(errorMessage),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
if (showRooms)
|
||||||
|
return const RoomsPage();
|
||||||
|
else
|
||||||
return const LoginPage();
|
return const LoginPage();
|
||||||
} else {
|
|
||||||
return const ChatsPage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
class RoomPage extends StatefulWidget {
|
||||||
|
const RoomPage({super.key, required this.room});
|
||||||
|
|
||||||
|
final Room room;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RoomPage> createState() => _RoomPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RoomPageState extends State<RoomPage> {
|
||||||
|
Timeline? timeline;
|
||||||
|
final chatController = TextEditingController();
|
||||||
|
StreamSubscription? updateListener;
|
||||||
|
|
||||||
|
void updateTimeline() async {
|
||||||
|
final newTimeline =
|
||||||
|
await widget.room.getTimeline(eventContextId: widget.room.fullyRead);
|
||||||
|
setState(() {
|
||||||
|
timeline = newTimeline;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
updateTimeline();
|
||||||
|
updateListener = widget.room.onUpdate.stream.listen((event) {
|
||||||
|
updateTimeline();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAvatar() async {
|
||||||
|
final participants = widget.room.getParticipants();
|
||||||
|
final picked = await FilePicker.platform.pickFiles(type: FileType.image);
|
||||||
|
if (picked == null) return;
|
||||||
|
final file = File(picked.files.single.path!);
|
||||||
|
final bytes = await file.readAsBytes();
|
||||||
|
final uri = await widget.room.client.uploadContent(bytes);
|
||||||
|
await widget.room.client.setAvatarUrl(participants[0].id, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
updateListener?.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendMessage() {}
|
||||||
|
|
||||||
|
List<Event>? get messages => timeline?.events
|
||||||
|
.where((element) => element.type == EventTypes.Message)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
List<Widget> getChildren() {
|
||||||
|
if (timeline == null) return [const CircularProgressIndicator()];
|
||||||
|
return [
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: messages?.length,
|
||||||
|
reverse: true,
|
||||||
|
itemBuilder: (context, index) => ListTile(
|
||||||
|
title: Text(
|
||||||
|
messages![index].senderFromMemoryOrFallback.displayName ??
|
||||||
|
""),
|
||||||
|
subtitle: Text(messages![index].body),
|
||||||
|
leading:
|
||||||
|
messages![index].senderFromMemoryOrFallback.avatarUrl !=
|
||||||
|
null
|
||||||
|
? CircleAvatar(
|
||||||
|
foregroundImage: NetworkImage(messages![index]
|
||||||
|
.senderFromMemoryOrFallback
|
||||||
|
.avatarUrl!
|
||||||
|
.getThumbnail(widget.room.client,
|
||||||
|
width: 50, height: 50)
|
||||||
|
.toString()))
|
||||||
|
: null,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: chatController,
|
||||||
|
textCapitalization: TextCapitalization.sentences,
|
||||||
|
textInputAction: TextInputAction.send,
|
||||||
|
decoration: const InputDecoration(hintText: 'Message'),
|
||||||
|
onFieldSubmitted: (value) async {
|
||||||
|
chatController.text = '';
|
||||||
|
await widget.room.sendTextEvent(value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
|
title: Text(widget.room
|
||||||
|
.getLocalizedDisplayname()
|
||||||
|
.replaceFirst(RegExp("Group with "), "")),
|
||||||
|
actions: [
|
||||||
|
IconButton(onPressed: setAvatar, icon: const Icon(Icons.image))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: getChildren(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+113
@@ -0,0 +1,113 @@
|
|||||||
|
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/login.dart';
|
||||||
|
import 'package:zenith/room.dart';
|
||||||
|
import 'package:zenith/zenith_client_provider.dart';
|
||||||
|
|
||||||
|
class RoomsPage extends StatefulWidget {
|
||||||
|
const RoomsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RoomsPage> createState() => _RoomsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RoomsPageState extends State<RoomsPage> {
|
||||||
|
bool loadingRooms = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendMessage() {}
|
||||||
|
|
||||||
|
void viewRoom(Room room) {
|
||||||
|
Navigator.push(
|
||||||
|
context, MaterialPageRoute(builder: (context) => RoomPage(room: room)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
|
title: const Text("Zenith"),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text("Log out?"),
|
||||||
|
actions: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text("Cancel")),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text("Confirm"),
|
||||||
|
onPressed: () async {
|
||||||
|
print("Logging out...");
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.remove("homeserver");
|
||||||
|
prefs.remove("username");
|
||||||
|
prefs.remove("password");
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
|
final provider = Provider.of<ZenithClientProvider>(
|
||||||
|
context,
|
||||||
|
listen: false);
|
||||||
|
await provider.client.logout();
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const LoginPage()),
|
||||||
|
(route) => false);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.logout))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Center(child: Consumer<ZenithClientProvider>(
|
||||||
|
builder: (context, provider, child) {
|
||||||
|
provider.client.onRoomState.stream.listen((event) {
|
||||||
|
setState(() {
|
||||||
|
loadingRooms = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (provider.client.rooms.isEmpty)
|
||||||
|
return const CircularProgressIndicator();
|
||||||
|
else
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: provider.client.rooms.length,
|
||||||
|
itemBuilder: (context, index) => ListTile(
|
||||||
|
title: Text(provider.client.rooms[index]
|
||||||
|
.getLocalizedDisplayname()
|
||||||
|
.replaceFirst(RegExp("Group with "), "")),
|
||||||
|
leading: CircleAvatar(
|
||||||
|
foregroundImage: NetworkImage(provider
|
||||||
|
.client.rooms[index].avatar
|
||||||
|
?.getThumbnail(provider.client,
|
||||||
|
width: 50, height: 50)
|
||||||
|
.toString() ??
|
||||||
|
"")),
|
||||||
|
onTap: () => viewRoom(provider.client.rooms[index]),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class ZenithClientProvider extends ChangeNotifier {
|
class ZenithClientProvider extends ChangeNotifier {
|
||||||
late Client _client;
|
final client = Client("zenith", databaseBuilder: (_) async {
|
||||||
|
final dir =
|
||||||
Client get client => _client;
|
await getApplicationSupportDirectory(); // Recommend path_provider package
|
||||||
|
final db = HiveCollectionsDatabase('matrix_example_chat', dir.path);
|
||||||
void setClient(Client newClient) {
|
await db.open();
|
||||||
_client = newClient;
|
return db;
|
||||||
notifyListeners();
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-1
@@ -145,6 +145,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
file_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: file_picker
|
||||||
|
sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -174,6 +182,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.17"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -328,6 +344,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
version: "1.8.3"
|
||||||
|
path_provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: path_provider
|
||||||
|
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.1"
|
||||||
|
path_provider_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_android
|
||||||
|
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.2"
|
||||||
|
path_provider_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_foundation
|
||||||
|
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -607,4 +647,4 @@ packages:
|
|||||||
version: "6.3.0"
|
version: "6.3.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.1.5 <4.0.0"
|
dart: ">=3.1.5 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ dependencies:
|
|||||||
flutter_openssl_crypto: ^0.3.0
|
flutter_openssl_crypto: ^0.3.0
|
||||||
provider: ^6.1.1
|
provider: ^6.1.1
|
||||||
shared_preferences: ^2.2.2
|
shared_preferences: ^2.2.2
|
||||||
|
file_picker: ^6.1.1
|
||||||
|
path_provider: ^2.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user