Compare commits
33
Commits
ff52298d2a
...
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 | ||
|
|
799c15321b | ||
|
|
b636eaaa57 | ||
|
|
02ab48521e | ||
|
|
d5e7316ee8 | ||
|
|
53203e3527 |
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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,16 +1,26 @@
|
||||
# zenith
|
||||
# Zenith
|
||||
|
||||
A new Flutter project.
|
||||
A matrix client for Android.
|
||||
|
||||
## Getting Started
|
||||
TODO: Add play store + f-droid store links.
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
# Screenshots
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
TODO: Add screenshots.
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
# Features
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
TODO: Add feature list.
|
||||
|
||||
# How to Build
|
||||
|
||||
First install dependencies:
|
||||
```
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
Then build the apk:
|
||||
|
||||
```
|
||||
flutter build apk
|
||||
```
|
||||
@@ -23,6 +23,8 @@ linter:
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` 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
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:label="zenith"
|
||||
android:name="${applicationName}"
|
||||
|
||||
+88
-47
@@ -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/rooms.dart';
|
||||
import 'package:zenith/zenith_client_provider.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
@@ -12,26 +16,53 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final serverController = TextEditingController();
|
||||
final usernameController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
bool loggingIn = false;
|
||||
String failedMessage = '';
|
||||
|
||||
void connectMatrix() async {
|
||||
debugPrint("Making the client...");
|
||||
final client = Client("zenith");
|
||||
client.onLoginStateChanged.stream.listen((event) {
|
||||
debugPrint("LoginState=${event.toString()}");
|
||||
void login() async {
|
||||
setState(() {
|
||||
loggingIn = true;
|
||||
});
|
||||
|
||||
debugPrint("Checking the homeserver...");
|
||||
await client.checkHomeserver(Uri.parse(serverController.text));
|
||||
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
||||
|
||||
debugPrint("Logging in...");
|
||||
await client.login(LoginType.mLoginPassword,
|
||||
try {
|
||||
await provider.client.checkHomeserver(Uri.parse(serverController.text));
|
||||
await provider.client.login(
|
||||
LoginType.mLoginPassword,
|
||||
password: passwordController.text,
|
||||
identifier: AuthenticationUserIdentifier(user: usernameController.text),
|
||||
password: passwordController.text);
|
||||
refreshToken: true,
|
||||
);
|
||||
} catch (error) {
|
||||
print(error);
|
||||
setState(() {
|
||||
failedMessage = error.toString();
|
||||
loggingIn = false;
|
||||
});
|
||||
|
||||
for (var room in client.rooms) {
|
||||
debugPrint(
|
||||
"Room ID: ${room.id}, Room Name: ${room.getLocalizedDisplayname()}");
|
||||
Future.delayed(const Duration(seconds: 10), () {
|
||||
setState(() {
|
||||
failedMessage = '';
|
||||
});
|
||||
});
|
||||
return;
|
||||
} finally {
|
||||
setState(() {
|
||||
loggingIn = false;
|
||||
});
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString("homeserver", serverController.text);
|
||||
prefs.setString("username", usernameController.text);
|
||||
prefs.setString("password", passwordController.text);
|
||||
|
||||
if (!mounted) return;
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => const RoomsPage()),
|
||||
(route) => false);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -41,41 +72,51 @@ class _LoginPageState extends State<LoginPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: const Text("Login"),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: serverController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Server', hintText: 'https://matrix.org'),
|
||||
),
|
||||
TextFormField(
|
||||
controller: usernameController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Username', hintText: 'john'),
|
||||
),
|
||||
TextFormField(
|
||||
controller: passwordController,
|
||||
decoration: const InputDecoration(labelText: 'Password'),
|
||||
obscureText: true,
|
||||
),
|
||||
],
|
||||
return Consumer<ZenithClientProvider>(
|
||||
builder: (context, provider, child) => Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: const Text("Login"),
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: connectMatrix,
|
||||
tooltip: 'Log in',
|
||||
child: const Icon(Icons.login),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: serverController,
|
||||
autocorrect: false,
|
||||
textCapitalization: TextCapitalization.none,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Server', hintText: 'https://matrix.org'),
|
||||
),
|
||||
TextFormField(
|
||||
controller: usernameController,
|
||||
autocorrect: false,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Username', hintText: 'john'),
|
||||
),
|
||||
TextFormField(
|
||||
controller: passwordController,
|
||||
autocorrect: false,
|
||||
decoration: const InputDecoration(labelText: 'Password'),
|
||||
obscureText: true,
|
||||
onFieldSubmitted: (value) => login(),
|
||||
),
|
||||
Text(failedMessage,
|
||||
style: Theme.of(context).textTheme.headlineSmall)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: loggingIn ? null : login,
|
||||
tooltip: 'Log in',
|
||||
child: loggingIn
|
||||
? const CircularProgressIndicator()
|
||||
: const Icon(Icons.login),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+63
-7
@@ -1,5 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:zenith/rooms.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: 'Flutter Demo',
|
||||
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,61 @@ class MyHomePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
bool showRooms = false;
|
||||
String errorMessage = "";
|
||||
|
||||
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;
|
||||
|
||||
if (!mounted) return;
|
||||
final provider = Provider.of<ZenithClientProvider>(context, listen: false);
|
||||
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
|
||||
void initState() {
|
||||
super.initState();
|
||||
getCreds();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const LoginPage();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
+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]),
|
||||
));
|
||||
},
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class ZenithClientProvider extends ChangeNotifier {
|
||||
final client = Client("zenith", databaseBuilder: (_) async {
|
||||
final dir =
|
||||
await getApplicationSupportDirectory(); // Recommend path_provider package
|
||||
final db = HiveCollectionsDatabase('matrix_example_chat', dir.path);
|
||||
await db.open();
|
||||
return db;
|
||||
});
|
||||
}
|
||||
@@ -5,6 +5,10 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
}
|
||||
|
||||
+166
-1
@@ -137,6 +137,22 @@ 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"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -166,11 +182,24 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
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 +344,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
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 +400,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 +448,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 +621,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 +647,4 @@ packages:
|
||||
version: "6.3.0"
|
||||
sdks:
|
||||
dart: ">=3.1.5 <4.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
flutter: ">=3.10.0"
|
||||
|
||||
@@ -39,6 +39,9 @@ dependencies:
|
||||
flutter_olm: ^1.4.1
|
||||
flutter_openssl_crypto: ^0.3.0
|
||||
provider: ^6.1.1
|
||||
shared_preferences: ^2.2.2
|
||||
file_picker: ^6.1.1
|
||||
path_provider: ^2.1.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user