mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
inital code WiP
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
import 'package:flutter_data/flutter_data.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:ndk/ndk.dart';
|
||||
|
||||
import 'package:zapstore/models/app_curation_set.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
@@ -11,6 +12,7 @@ import 'package:zapstore/models/local_app.dart';
|
||||
import 'package:zapstore/models/release.dart';
|
||||
import 'package:zapstore/models/settings.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
import 'package:zapstore/utils/nwc_notifier.dart';
|
||||
|
||||
final adapterProvidersMap = <String, Provider<Adapter<DataModelMixin>>>{
|
||||
'appCurationSets': appCurationSetsAdapterProvider,
|
||||
@@ -50,4 +52,13 @@ extension AdapterRefX on Ref {
|
||||
Adapter<Settings> get settings =>
|
||||
watch(settingsAdapterProvider)..internalWatch = watch;
|
||||
Adapter<User> get users => watch(usersAdapterProvider)..internalWatch = watch;
|
||||
|
||||
}
|
||||
|
||||
final nwcSecretProvider =
|
||||
StateNotifierProvider<NwcSecretNotifier, String?>((ref) {
|
||||
return NwcSecretNotifier();
|
||||
});
|
||||
|
||||
final ndk = Ndk.emptyBootstrapRelaysConfig();
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:ndk/domain_layer/usecases/nwc/consts/nwc_method.dart';
|
||||
import 'package:ndk/domain_layer/usecases/nwc/nwc_connection.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/feedback.dart';
|
||||
@@ -26,12 +28,16 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final systemInfoState = ref.watch(systemInfoNotifierProvider);
|
||||
|
||||
final controller = useTextEditingController();
|
||||
final feedbackController = useTextEditingController();
|
||||
final nwcController = useTextEditingController();
|
||||
final user = ref.settings
|
||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
||||
.model!
|
||||
.user
|
||||
.value;
|
||||
final isTextFieldEmpty = useState(true);
|
||||
|
||||
final nwcSecret = ref.watch(nwcSecretProvider);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
@@ -51,7 +57,7 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
Text('Comments, suggestions and error reports welcome here.'),
|
||||
Gap(20),
|
||||
TextField(
|
||||
controller: controller,
|
||||
controller: feedbackController,
|
||||
maxLines: 10,
|
||||
),
|
||||
Gap(20),
|
||||
@@ -61,9 +67,9 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
loadingWidget: SizedBox(
|
||||
width: 14, height: 14, child: CircularProgressIndicator()),
|
||||
onPressed: () async {
|
||||
if (controller.text.trim().isNotEmpty) {
|
||||
if (feedbackController.text.trim().isNotEmpty) {
|
||||
final text =
|
||||
'${controller.text.trim()} [from ${user.npub} on ${DateFormat('MMMM d, y').format(DateTime.now())}]';
|
||||
'${feedbackController.text.trim()} [from ${user.npub} on ${DateFormat('MMMM d, y').format(DateTime.now())}]';
|
||||
final event = AppFeedback(content: text).sign(kI);
|
||||
try {
|
||||
await http.post(Uri.parse('https://relay.zapstore.dev/'),
|
||||
@@ -73,7 +79,7 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
context.showInfo('Thank you',
|
||||
description: 'Message sent successfully');
|
||||
}
|
||||
controller.clear();
|
||||
feedbackController.clear();
|
||||
} catch (e, stack) {
|
||||
if (context.mounted) {
|
||||
context.showError(
|
||||
@@ -96,6 +102,81 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
Gap(40),
|
||||
Divider(),
|
||||
Gap(40),
|
||||
if (user != null)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Gap(20),
|
||||
Text(
|
||||
"Nostr Wallet Connect ${nwcSecret != null ? 'connected' : 'URI'}"),
|
||||
if (nwcSecret != null && nwcSecret != '')
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(nwcSecretProvider.notifier)
|
||||
.updateNwcSecret(null);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
disabledBackgroundColor: Colors.transparent,
|
||||
backgroundColor: Colors.transparent),
|
||||
child: Text('Disconnect'),
|
||||
),
|
||||
if (nwcSecret == null || nwcSecret == '')
|
||||
TextField(
|
||||
autocorrect: false,
|
||||
controller: nwcController,
|
||||
onChanged: (value) {
|
||||
isTextFieldEmpty.value = value.isEmpty;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'nostr+walletconnect://...',
|
||||
suffixIcon: AsyncButtonBuilder(
|
||||
disabled: isTextFieldEmpty.value,
|
||||
loadingWidget: SizedBox(
|
||||
width: 14,
|
||||
height: 14,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
onPressed: () async {
|
||||
final nwcUri = nwcController.text.trim();
|
||||
NwcConnection connection = await ndk.nwc.connect(nwcUri, doGetInfoMethod: true, onError: (error) {
|
||||
context.showError(
|
||||
title: 'Unable to connect',
|
||||
description: error);
|
||||
});
|
||||
if (connection.info!=null && connection.permissions.contains(NwcMethod.PAY_INVOICE.name)) {
|
||||
await ref
|
||||
.read(nwcSecretProvider.notifier)
|
||||
.updateNwcSecret(nwcUri);
|
||||
} else {
|
||||
context.showError(
|
||||
title: 'Wallet missing pay_invoice permission',
|
||||
description: '');
|
||||
}
|
||||
},
|
||||
builder: (context, child, callback, buttonState) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
onPressed: callback,
|
||||
style: ElevatedButton.styleFrom(
|
||||
disabledBackgroundColor: Colors.transparent,
|
||||
backgroundColor: Colors.transparent),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text('Connect'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Gap(40),
|
||||
Divider(),
|
||||
Gap(40),
|
||||
Text(
|
||||
'Tools',
|
||||
style: context.theme.textTheme.headlineLarge!
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter_data/flutter_data.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
class NwcSecretNotifier extends StateNotifier<String?> {
|
||||
final _storage = const FlutterSecureStorage();
|
||||
|
||||
NwcSecretNotifier() : super(null) {
|
||||
_loadNwcSecret();
|
||||
}
|
||||
|
||||
Future<void> _loadNwcSecret() async {
|
||||
final secret = await _storage.read(key: 'nwc_secret');
|
||||
state = secret;
|
||||
}
|
||||
|
||||
Future<void> updateNwcSecret(String? newSecret) async {
|
||||
if (newSecret != null) {
|
||||
await _storage.write(key: 'nwc_secret', value: newSecret);
|
||||
} else {
|
||||
await _storage.delete(key: 'nwc_secret');
|
||||
}
|
||||
await _loadNwcSecret();
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||
#include <gtk/gtk_plugin.h>
|
||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) gtk_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
|
||||
gtk_plugin_register_with_registrar(gtk_registrar);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
flutter_secure_storage_linux
|
||||
gtk
|
||||
sqlite3_flutter_libs
|
||||
url_launcher_linux
|
||||
|
||||
@@ -7,6 +7,7 @@ import Foundation
|
||||
|
||||
import app_links
|
||||
import device_info_plus
|
||||
import flutter_secure_storage_macos
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import sqflite_darwin
|
||||
@@ -16,6 +17,7 @@ import url_launcher_macos
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
|
||||
+49
-1
@@ -452,6 +452,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.2.2"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@@ -767,7 +815,7 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
ndk:
|
||||
dependency: "direct overridden"
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "packages/ndk"
|
||||
ref: c279076973ff7b017697f4fbd172738535756c50
|
||||
|
||||
@@ -51,6 +51,8 @@ dependencies:
|
||||
background_downloader: ^8.8.0
|
||||
mutex: ^3.1.0
|
||||
easy_image_viewer: ^1.5.1
|
||||
flutter_secure_storage: ^9.2.2
|
||||
ndk: ^0.2.0-dev005
|
||||
|
||||
dependency_overrides:
|
||||
ndk:
|
||||
|
||||
Reference in New Issue
Block a user