Skip to content

Add account system and server list #47

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

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Build flutter_rust_bridge bindings
if: matrix.projects == 'plugin'
run: |
cargo install flutter_rust_bridge_codegen@2.9.0
cargo install flutter_rust_bridge_codegen@2.10.0
flutter_rust_bridge_codegen generate
- name: Run build_runner
if: matrix.projects == 'api' || matrix.projects == 'app'
Expand Down
4 changes: 2 additions & 2 deletions api/lib/src/models/vector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class VectorDefinition with VectorDefinitionMappable {

String toDisplayString() => '($x, $y)';

operator +(VectorDefinition other) =>
VectorDefinition operator +(VectorDefinition other) =>
VectorDefinition(x + other.x, y + other.y);
operator -(VectorDefinition other) =>
VectorDefinition operator -(VectorDefinition other) =>
VectorDefinition(x - other.x, y - other.y);

bool inBounds(VectorDefinition first, VectorDefinition last) {
Expand Down
14 changes: 7 additions & 7 deletions api/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.1.0"
ffi:
dependency: transitive
description:
Expand Down Expand Up @@ -294,10 +294,10 @@ packages:
dependency: "direct dev"
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
url: "https://pub.dev"
source: hosted
version: "5.1.1"
version: "6.0.0"
logging:
dependency: transitive
description:
Expand Down Expand Up @@ -472,10 +472,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "6c7653816b1c938e121b69ff63a33c9dc68102b65a5fb0a5c0f9786256ed33e6"
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
source: hosted
version: "0.7.5"
version: "0.7.6"
timing:
dependency: transitive
description:
Expand Down Expand Up @@ -541,4 +541,4 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.7.0 <4.0.0"
dart: ">=3.8.0-0 <4.0.0"
2 changes: 1 addition & 1 deletion api/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ dependencies:
# path: ^1.8.0

dev_dependencies:
lints: ^5.0.0
lints: ^6.0.0
dart_mappable_builder: ^4.2.3
build_runner: ^2.4.12
4 changes: 3 additions & 1 deletion app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -249,5 +249,7 @@
"desktop": "Desktop",
"compact": "Compact",
"standard": "Standard",
"comfortable": "Comfortable"
"comfortable": "Comfortable",
"accounts": "Accounts",
"create": "Create"
}
24 changes: 6 additions & 18 deletions app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import 'package:material_leap/material_leap.dart';
import 'package:setonix/pages/editor/shell.dart';
import 'package:setonix/pages/game/page.dart';
import 'package:setonix/pages/home/page.dart';
import 'package:setonix/pages/settings/data.dart';
import 'package:setonix/pages/settings/general.dart';
import 'package:setonix/pages/settings/personalization.dart';
import 'package:setonix/services/file_system.dart';
import 'package:setonix/services/network.dart';
import 'package:setonix/theme.dart';
Expand Down Expand Up @@ -157,21 +154,12 @@ class SetonixApp extends StatelessWidget {
GoRoute(
path: 'settings',
builder: (context, state) => const SettingsPage(),
routes: [
GoRoute(
path: 'general',
builder: (context, state) => const GeneralSettingsPage(),
),
GoRoute(
path: 'data',
builder: (context, state) => const DataSettingsPage(),
),
GoRoute(
path: 'personalization',
builder: (context, state) =>
const PersonalizationSettingsPage(),
),
],
routes: SettingsView.values
.map((e) => GoRoute(
path: e.name,
builder: (context, state) => e.buildContent(),
))
.toList(),
),
],
),
Expand Down
86 changes: 86 additions & 0 deletions app/lib/pages/settings/accounts.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lw_file_system/lw_file_system.dart';
import 'package:setonix/src/generated/i18n/app_localizations.dart';
import 'package:material_leap/material_leap.dart';
import 'package:phosphor_flutter/phosphor_flutter.dart';
import 'package:setonix/services/file_system.dart';

import '../../bloc/settings.dart';

class AccountsSettingsPage extends StatefulWidget {
final bool inView;
const AccountsSettingsPage({super.key, this.inView = false});

@override
State<AccountsSettingsPage> createState() => _AccountsSettingsPageState();
}

class _AccountsSettingsPageState extends State<AccountsSettingsPage> {
late final KeyFileSystem _privateKeyFileSystem, _publicKeyFileSystem;
Future<List<String>>? _keysFuture;
late final SetonixFileSystem _fileSystem;

@override
void initState() {
super.initState();
_fileSystem = context.read<SetonixFileSystem>();
_privateKeyFileSystem = _fileSystem.privateKeySystem;
_publicKeyFileSystem = _fileSystem.publicKeySystem;
_buildKeysFuture();
}

void _buildKeysFuture() {
_keysFuture = _privateKeyFileSystem.getKeys();
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: widget.inView ? Colors.transparent : null,
appBar: WindowTitleBar<SettingsCubit, SetonixSettings>(
inView: widget.inView,
backgroundColor: widget.inView ? Colors.transparent : null,
title: Text(AppLocalizations.of(context).accounts),
),
body: FutureBuilder<List<String>>(
future: _keysFuture,
builder: (context, state) {
final keys = state.data ?? <String>[];
return ListView.builder(
itemCount: keys.length,
itemBuilder: (context, index) {
final key = keys[index];
return Dismissible(
key: Key(key),
child: ListTile(
title: Text(key.substring(1)),
),
onDismissed: (direction) {
_privateKeyFileSystem.deleteFile(key);
_publicKeyFileSystem.deleteFile(key);
setState(() {
keys.removeAt(index);
});
},
);
},
);
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () async {
final name = await showDialog(
context: context, builder: (context) => NameDialog());
if (name == null) return;
await _fileSystem.generateKey(name);
setState(() {
_buildKeysFuture();
});
},
label: Text(AppLocalizations.of(context).add),
icon: const PhosphorIcon(PhosphorIconsLight.plus),
),
);
}
}
21 changes: 14 additions & 7 deletions app/lib/pages/settings/home.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:setonix/pages/settings/accounts.dart';
import 'package:setonix/pages/settings/input.dart';
import 'package:setonix/src/generated/i18n/app_localizations.dart';
import 'package:go_router/go_router.dart';
Expand All @@ -13,6 +14,7 @@ enum SettingsView {
general,
data,
personalization,
accounts,
inputs;

bool get isEnabled => true;
Expand All @@ -22,16 +24,27 @@ enum SettingsView {
SettingsView.data => AppLocalizations.of(context).data,
SettingsView.personalization =>
AppLocalizations.of(context).personalization,
SettingsView.accounts => AppLocalizations.of(context).accounts,
SettingsView.inputs => AppLocalizations.of(context).inputs,
};

IconGetter get icon => switch (this) {
SettingsView.general => PhosphorIcons.gear,
SettingsView.data => PhosphorIcons.database,
SettingsView.personalization => PhosphorIcons.monitor,
SettingsView.accounts => PhosphorIcons.user,
SettingsView.inputs => PhosphorIcons.keyboard,
};
String get path => '/settings/$name';

Widget buildContent({bool inView = false}) => switch (this) {
SettingsView.general => GeneralSettingsPage(inView: inView),
SettingsView.data => DataSettingsPage(inView: inView),
SettingsView.personalization =>
PersonalizationSettingsPage(inView: inView),
SettingsView.accounts => AccountsSettingsPage(inView: inView),
SettingsView.inputs => InputsSettingsPage(inView: inView),
};
}

class SettingsPage extends StatefulWidget {
Expand Down Expand Up @@ -118,13 +131,7 @@ class _SettingsPageState extends State<SettingsPage> {
if (isMobile) {
return navigation;
}
final content = switch (_view) {
SettingsView.general => const GeneralSettingsPage(inView: true),
SettingsView.data => const DataSettingsPage(inView: true),
SettingsView.personalization =>
const PersonalizationSettingsPage(inView: true),
SettingsView.inputs => const InputsSettingsPage(inView: true),
};
final content = _view.buildContent(inView: true);
return Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
SizedBox(width: 300, child: navigation),
Expanded(child: content),
Expand Down
40 changes: 40 additions & 0 deletions app/lib/services/file_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:collection';
import 'dart:convert';
import 'dart:typed_data';

import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:file_selector/file_selector.dart' as fs;
import 'package:http/http.dart' as http;
import 'package:idb_shim/idb.dart';
Expand Down Expand Up @@ -34,12 +35,16 @@ class SetonixFileSystem {
worldSystem,
editorSystem;
final TypedKeyFileSystem<DataMetadata> dataInfoSystem;
final KeyFileSystem privateKeySystem, publicKeySystem;

static Future<void> _onDatabaseUpgrade(VersionChangeEvent event) async {
await initStores(event, ['packs', 'templates', 'worlds']);
if (event.oldVersion < 2) {
event.database.createObjectStore('packs-data');
}
if (event.oldVersion < 3) {
event.database.createObjectStore('keys');
}
}

static const kDatabaseVersion = 2;
Expand Down Expand Up @@ -116,6 +121,30 @@ class SetonixFileSystem {
),
onDecode: SetonixData.fromData,
onEncode: (data) => data.exportAsBytes(),
),
privateKeySystem = KeyFileSystem.fromPlatform(
FileSystemConfig(
passwordStorage: SecureStoragePasswordStorage(),
storeName: 'keys',
getDirectory: (storage) async =>
'${await getSetonixDirectory()}/Keys',
database: 'setonix.db',
databaseVersion: kDatabaseVersion,
keySuffix: '.key',
onDatabaseUpgrade: _onDatabaseUpgrade,
),
),
publicKeySystem = KeyFileSystem.fromPlatform(
FileSystemConfig(
passwordStorage: SecureStoragePasswordStorage(),
storeName: 'keys',
getDirectory: (storage) async =>
'${await getSetonixDirectory()}/Keys',
database: 'setonix.db',
databaseVersion: kDatabaseVersion,
keySuffix: '.pub',
onDatabaseUpgrade: _onDatabaseUpgrade,
),
);

Future<SetonixFile?> fetchCorePack() async =>
Expand Down Expand Up @@ -197,4 +226,15 @@ class SetonixFileSystem {
await updateServerLastUsed(pack, serverAddress);
}
}

Future<void> generateKey(String name) async {
final generator = Ed25519();
final keyPair = await generator.newKeyPair();
final privateKey = await keyPair.extractPrivateKeyBytes();
final publicKey = await keyPair.extractPublicKey();
await privateKeySystem.createFileWithName(Uint8List.fromList(privateKey),
name: name);
await publicKeySystem
.createFileWithName(Uint8List.fromList(publicKey.bytes), name: name);
}
}
Loading
Loading