From ab5a3dab211213380c80832caaf4489fa664721f Mon Sep 17 00:00:00 2001 From: redsolver Date: Tue, 6 Jun 2023 14:16:42 +0200 Subject: [PATCH] Version 0.14.1 Beta --- lib/page/settings/portal_auth.dart | 60 +++++++++++++++++++++++++++++- lib/service/mysky.dart | 43 ++++++++++++++++++--- lib/service/pinning_service.dart | 5 +++ lib/service/s5_api_provider.dart | 20 ++++++++++ lib/view/active_queue_tasks.dart | 3 +- lib/view/sidebar.dart | 2 +- lib/widget/user.dart | 2 +- pubspec.lock | 2 +- pubspec.yaml | 2 +- windows/runner/Runner.rc | 2 +- 10 files changed, 128 insertions(+), 13 deletions(-) create mode 100644 lib/service/s5_api_provider.dart diff --git a/lib/page/settings/portal_auth.dart b/lib/page/settings/portal_auth.dart index f051dbb..3391472 100644 --- a/lib/page/settings/portal_auth.dart +++ b/lib/page/settings/portal_auth.dart @@ -291,7 +291,8 @@ class _PortalAuthSettingsPageState extends State { SizedBox( height: 8, ), - Row( + Wrap( + runSpacing: 10, children: [ ElevatedButton( onPressed: () async { @@ -402,6 +403,8 @@ class _PortalAuthSettingsPageState extends State { context.pop(); context.pop(); setState(() {}); + + quotaService.update(); } catch (e, st) { context.pop(); showErrorDialog(context, e, st); @@ -604,11 +607,19 @@ class _PortalAuthSettingsPageState extends State { ); if (dialogRes == true) { showLoadingDialog(context, 'Adding Sia Store...'); + String workerApiUrl = workerApiUrlCtrl.text; + if (workerApiUrl.endsWith('/')) { + workerApiUrl = + workerApiUrl.substring(0, workerApiUrl.length - 1); + } + if (Uri.parse(workerApiUrl).path.length < 3) { + workerApiUrl += '/api/worker'; + } mySky.portalAccounts['_local'] = { 'store': { 'sia': { - 'workerApiUrl': workerApiUrlCtrl.text, + 'workerApiUrl': workerApiUrl, 'apiPassword': apiPasswordCtrl.text, 'downloadUrl': downloadUrlCtrl.text, } @@ -638,6 +649,8 @@ class _PortalAuthSettingsPageState extends State { context.pop(); setState(() {}); + + quotaService.update(); } } catch (e, st) { showErrorDialog(context, e, st); @@ -658,6 +671,49 @@ class _PortalAuthSettingsPageState extends State { 'Advanced', style: titleTextStyle, ), + if (s5Node.store != null) + Padding( + padding: const EdgeInsets.only(top: 6), + child: Text( + 'Important: If a local store is configured, all new files and metadata are uploaded to the local store.', + ), + ), + SizedBox( + height: 6, + ), + Row( + children: [ + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Storage Services JSON'), + content: SizedBox( + width: dialogWidth, + height: dialogHeight, + child: SingleChildScrollView( + reverse: true, + child: SelectableText( + const JsonEncoder.withIndent(' ').convert( + mySky.portalAccounts, + ), + style: const TextStyle( + fontFamily: 'monospace', + fontSize: 16, + ), + ), + ), + ), + ), + ); + }, + child: Text( + 'View full JSON', + ), + ), + ], + ), SizedBox( height: 12, ), diff --git a/lib/service/mysky.dart b/lib/service/mysky.dart index c9aa593..69f9697 100644 --- a/lib/service/mysky.dart +++ b/lib/service/mysky.dart @@ -17,10 +17,11 @@ import 'package:lib5/storage_service.dart'; import 'package:lib5/util.dart'; import 'package:vup/service/base.dart'; import 'package:http/http.dart' as http; +import 'package:vup/service/s5_api_provider.dart'; class MySkyService extends VupService { late final CryptoImplementation crypto; - late S5APIProviderWithRemoteUpload api; + late VupS5ApiProvider api; late S5UserIdentity identity; @@ -45,11 +46,24 @@ class MySkyService extends VupService { 's5-deleted-cids', ); - api = S5NodeAPIProviderWithRemoteUpload(s5Node, deletedCIDs: deletedCIDs); + api = VupS5ApiProvider(s5Node, deletedCIDs: deletedCIDs); } late Map portalAccounts; + List get fileUploadServiceOrder => + (portalAccounts['fileUploadServiceOrder'] ?? + portalAccounts['uploadPortalOrder']) + ?.cast(); + + List get metadataUploadServiceOrder => + (portalAccounts['metadataUploadServiceOrder'] ?? + portalAccounts['uploadPortalOrder']) + ?.cast(); + + List get allUploadServices => + (fileUploadServiceOrder + metadataUploadServiceOrder).toSet().toList(); + Future loadPortalAccounts() async { final res = await hiddenDB.getJSON( portalAccountsPath, @@ -119,6 +133,16 @@ class MySkyService extends VupService { await loadPortalAccounts(); } + void initS5Store() async { + try { + await s5Node.store!.init(); + // TODO Configurable + s5Node.exposeStore = true; + } catch (e, st) { + logger.catched(e, st); + } + } + Future setupPortalAccounts() async { if (!dataBox.containsKey('portal_accounts')) { return; @@ -139,9 +163,8 @@ class MySkyService extends VupService { node: s5Node, ); s5Node.store = stores.values.first; - await s5Node.store!.init(); - // TODO Configurable - s5Node.exposeStore = true; + + initS5Store(); } continue; } @@ -178,6 +201,7 @@ class MySkyService extends VupService { for (final uc in storageServiceConfigs) { connectToPortalNodes(uc); } + refreshPortalAccounts(); } void connectToPortalNodes(StorageServiceConfig pc) async { @@ -210,6 +234,15 @@ class MySkyService extends VupService { final isLoggedIn = Observable(initialValue: null); + // TODO Apply changes + Future refreshPortalAccounts() async { + try { + await loadPortalAccounts(); + } catch (e, st) { + logger.catched(e, st); + } + } + Future autoLogin() async { info('autoLogin'); final authPayload = await loadAuthPayload(); diff --git a/lib/service/pinning_service.dart b/lib/service/pinning_service.dart index 0fba265..b4a7382 100644 --- a/lib/service/pinning_service.dart +++ b/lib/service/pinning_service.dart @@ -117,6 +117,11 @@ class PinningService extends VupService { } } } + if (s5Node.store != null) { + if (await s5Node.store!.contains(cid.hash)) { + await s5Node.store!.delete(cid.hash); + } + } } } } diff --git a/lib/service/s5_api_provider.dart b/lib/service/s5_api_provider.dart new file mode 100644 index 0000000..117692e --- /dev/null +++ b/lib/service/s5_api_provider.dart @@ -0,0 +1,20 @@ +import 'dart:typed_data'; + +import 'package:hive/hive.dart'; +import 'package:lib5/lib5.dart'; +import 'package:s5_server/api.dart'; +import 'package:s5_server/node.dart'; + +class VupS5ApiProvider extends S5NodeAPIProviderWithRemoteUpload { + VupS5ApiProvider(S5Node node, {required Box deletedCIDs}) + : super(node, deletedCIDs: deletedCIDs); + + @override + Future uploadRawFile(Uint8List data) async { + if (node.store != null) { + return node.uploadRawFile(data); + } else { + return super.uploadRawFile(data); + } + } +} diff --git a/lib/view/active_queue_tasks.dart b/lib/view/active_queue_tasks.dart index 7dce66f..899d195 100644 --- a/lib/view/active_queue_tasks.dart +++ b/lib/view/active_queue_tasks.dart @@ -1,4 +1,5 @@ import 'package:vup/app.dart'; +import 'package:vup/queue/mdl.dart'; import 'package:vup/queue/sync.dart'; import 'package:vup/view/queue_task_manager.dart'; @@ -38,7 +39,7 @@ class _ActiveQueueTasksViewState extends State { Padding( padding: const EdgeInsets.all(2.0), child: Text( - '${task is SyncQueueTask ? 'Sync' : task.toString()} ${task.id}', + '${task is SyncQueueTask ? 'Sync' : task is MediaDownloadQueueTask ? 'Download' : task.toString()} ${task.id}', ), ), if (task.progress > 0) diff --git a/lib/view/sidebar.dart b/lib/view/sidebar.dart index e194236..2950ede 100644 --- a/lib/view/sidebar.dart +++ b/lib/view/sidebar.dart @@ -572,7 +572,7 @@ MimeType=x-scheme-handler/vup; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - for (final key in mySky.portalAccounts['uploadPortalOrder']) + for (final key in mySky.allUploadServices) QuotaWidget(context: context, portal: key), if (quotaService.accountInfos.length < 2) Padding( diff --git a/lib/widget/user.dart b/lib/widget/user.dart index bd55fdf..8006b20 100644 --- a/lib/widget/user.dart +++ b/lib/widget/user.dart @@ -85,7 +85,7 @@ class _UserWidgetState extends State { overflow: TextOverflow.ellipsis, ), Text( - 'v0.14.0 Beta', + 'v0.14.1 Beta', // profile!.location ?? '', overflow: TextOverflow.ellipsis, ), diff --git a/pubspec.lock b/pubspec.lock index 9f4c73a..3057306 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1548,7 +1548,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "891205e50145aa2900bb46724c899aaea1a0ce38" + resolved-ref: eeb1f8cee2d01a17dc2c0a7c5cdcf8729abae6e8 url: "https://github.com/s5-dev/S5.git" source: git version: "0.11.3" diff --git a/pubspec.yaml b/pubspec.yaml index 1bd2343..57ab618 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.14.0+1400 +version: 0.14.1+1401 environment: sdk: ">=2.13.0 <3.0.0" diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index 8aa29d6..50de8c5 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -69,7 +69,7 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" #ifdef FLUTTER_BUILD_NAME #define VERSION_AS_STRING #FLUTTER_BUILD_NAME #else -#define VERSION_AS_STRING "0.14.0" +#define VERSION_AS_STRING "0.14.1" #endif VS_VERSION_INFO VERSIONINFO