Browse Source

refactor(app,neon,neon_files,neon_news,neon_notes,neon_notifications): Use named imports

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/935/head
jld3103 1 year ago
parent
commit
0be6026afc
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 6
      packages/app/integration_test/screenshot_test.dart
  2. 2
      packages/app/pubspec.lock
  3. 4
      packages/app/pubspec.yaml
  4. 1
      packages/neon/neon/lib/nextcloud.dart
  5. 3
      packages/neon/neon/lib/src/app.dart
  6. 2
      packages/neon/neon/lib/src/blocs/accounts.dart
  7. 5
      packages/neon/neon/lib/src/blocs/apps.dart
  8. 6
      packages/neon/neon/lib/src/blocs/capabilities.dart
  9. 1
      packages/neon/neon/lib/src/blocs/login_check_account.dart
  10. 5
      packages/neon/neon/lib/src/blocs/login_check_server_status.dart
  11. 11
      packages/neon/neon/lib/src/blocs/login_flow.dart
  12. 2
      packages/neon/neon/lib/src/blocs/next_push.dart
  13. 4
      packages/neon/neon/lib/src/blocs/push_notifications.dart
  14. 24
      packages/neon/neon/lib/src/blocs/unified_search.dart
  15. 6
      packages/neon/neon/lib/src/blocs/user_details.dart
  16. 13
      packages/neon/neon/lib/src/blocs/user_statuses.dart
  17. 4
      packages/neon/neon/lib/src/models/app_implementation.dart
  18. 4
      packages/neon/neon/lib/src/models/push_notification.dart
  19. 2
      packages/neon/neon/lib/src/models/push_notification.g.dart
  20. 4
      packages/neon/neon/lib/src/pages/account_settings.dart
  21. 2
      packages/neon/neon/lib/src/pages/home.dart
  22. 6
      packages/neon/neon/lib/src/pages/login_check_server_status.dart
  23. 4
      packages/neon/neon/lib/src/theme/theme.dart
  24. 14
      packages/neon/neon/lib/src/utils/push_utils.dart
  25. 4
      packages/neon/neon/lib/src/widgets/account_tile.dart
  26. 4
      packages/neon/neon/lib/src/widgets/drawer.dart
  27. 12
      packages/neon/neon/lib/src/widgets/unified_search_results.dart
  28. 5
      packages/neon/neon/lib/src/widgets/user_avatar.dart
  29. 5
      packages/neon/neon_files/lib/neon_files.dart
  30. 2
      packages/neon/neon_files/lib/routes.dart
  31. 4
      packages/neon/neon_files/pubspec.yaml
  32. 2
      packages/neon/neon_news/lib/blocs/article.dart
  33. 34
      packages/neon/neon_news/lib/blocs/articles.dart
  34. 22
      packages/neon/neon_news/lib/blocs/news.dart
  35. 4
      packages/neon/neon_news/lib/dialogs/add_feed.dart
  36. 2
      packages/neon/neon_news/lib/dialogs/feed_show_url.dart
  37. 2
      packages/neon/neon_news/lib/dialogs/feed_update_error.dart
  38. 6
      packages/neon/neon_news/lib/dialogs/move_feed.dart
  39. 6
      packages/neon/neon_news/lib/neon_news.dart
  40. 2
      packages/neon/neon_news/lib/pages/feed.dart
  41. 2
      packages/neon/neon_news/lib/pages/folder.dart
  42. 2
      packages/neon/neon_news/lib/routes.dart
  43. 2
      packages/neon/neon_news/lib/sort/articles.dart
  44. 2
      packages/neon/neon_news/lib/sort/feeds.dart
  45. 2
      packages/neon/neon_news/lib/sort/folders.dart
  46. 10
      packages/neon/neon_news/lib/widgets/articles_view.dart
  47. 2
      packages/neon/neon_news/lib/widgets/feed_icon.dart
  48. 10
      packages/neon/neon_news/lib/widgets/feeds_view.dart
  49. 10
      packages/neon/neon_news/lib/widgets/folder_select.dart
  50. 2
      packages/neon/neon_news/lib/widgets/folder_view.dart
  51. 4
      packages/neon/neon_news/lib/widgets/folders_view.dart
  52. 4
      packages/neon/neon_news/pubspec.yaml
  53. 6
      packages/neon/neon_notes/lib/blocs/note.dart
  54. 12
      packages/neon/neon_notes/lib/blocs/notes.dart
  55. 4
      packages/neon/neon_notes/lib/dialogs/create_note.dart
  56. 4
      packages/neon/neon_notes/lib/dialogs/select_category.dart
  57. 6
      packages/neon/neon_notes/lib/neon_notes.dart
  58. 2
      packages/neon/neon_notes/lib/routes.dart
  59. 2
      packages/neon/neon_notes/lib/sort/notes.dart
  60. 4
      packages/neon/neon_notes/lib/widgets/categories_view.dart
  61. 16
      packages/neon/neon_notes/lib/widgets/notes_view.dart
  62. 4
      packages/neon/neon_notes/pubspec.yaml
  63. 16
      packages/neon/neon_notifications/lib/blocs/notifications.dart
  64. 6
      packages/neon/neon_notifications/lib/neon_notifications.dart
  65. 6
      packages/neon/neon_notifications/lib/pages/main.dart
  66. 2
      packages/neon/neon_notifications/lib/routes.dart
  67. 4
      packages/neon/neon_notifications/pubspec.yaml

6
packages/app/integration_test/screenshot_test.dart

@ -9,9 +9,13 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
import 'package:neon/models.dart'; import 'package:neon/models.dart';
import 'package:neon/neon.dart'; import 'package:neon/neon.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/settings.dart'; import 'package:neon/settings.dart';
import 'package:neon_files/widgets/actions.dart'; import 'package:neon_files/widgets/actions.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/news.dart' as news;
import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/notes.dart' as notes;
import 'package:nextcloud/notifications.dart' as notifications;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
Future<void> runTestApp( Future<void> runTestApp(

2
packages/app/pubspec.lock

@ -653,7 +653,7 @@ packages:
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
nextcloud: nextcloud:
dependency: "direct overridden" dependency: "direct dev"
description: description:
path: "../nextcloud" path: "../nextcloud"
relative: true relative: true

4
packages/app/pubspec.yaml

@ -41,6 +41,10 @@ dev_dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon_lints path: packages/neon_lints
nextcloud:
git:
url: https://github.com/nextcloud/neon
path: packages/nextcloud
shared_preferences: any shared_preferences: any
vector_graphics_compiler: any vector_graphics_compiler: any

1
packages/neon/neon/lib/nextcloud.dart

@ -1 +0,0 @@
export 'package:nextcloud/nextcloud.dart';

3
packages/neon/neon/lib/src/app.dart

@ -22,6 +22,7 @@ import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/localizations.dart'; import 'package:neon/src/utils/localizations.dart';
import 'package:neon/src/utils/provider.dart'; import 'package:neon/src/utils/provider.dart';
import 'package:neon/src/utils/push_utils.dart'; import 'package:neon/src/utils/push_utils.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:quick_actions/quick_actions.dart'; import 'package:quick_actions/quick_actions.dart';
import 'package:tray_manager/tray_manager.dart' as tray; import 'package:tray_manager/tray_manager.dart' as tray;
@ -284,7 +285,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
stream: _accountsBloc.activeAccount, stream: _accountsBloc.activeAccount,
builder: (final context, final activeAccountSnapshot) { builder: (final context, final activeAccountSnapshot) {
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
return ResultBuilder<CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data?>.behaviorSubject( return ResultBuilder<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data?>.behaviorSubject(
stream: activeAccountSnapshot.hasData stream: activeAccountSnapshot.hasData
? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities ? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities
: null, : null,

2
packages/neon/neon/lib/src/blocs/accounts.dart

@ -16,7 +16,7 @@ import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/settings/models/storage.dart'; import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/account_options.dart'; import 'package:neon/src/utils/account_options.dart';
import 'package:neon/src/utils/global_options.dart'; import 'package:neon/src/utils/global_options.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
const _keyAccounts = 'accounts'; const _keyAccounts = 'accounts';

5
packages/neon/neon/lib/src/blocs/apps.dart

@ -11,6 +11,7 @@ import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/models/notifications_interface.dart'; import 'package:neon/src/models/notifications_interface.dart';
import 'package:neon/src/settings/models/options_collection.dart'; import 'package:neon/src/settings/models/options_collection.dart';
import 'package:neon/src/utils/request_manager.dart'; import 'package:neon/src/utils/request_manager.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@ -26,7 +27,7 @@ abstract interface class AppsBlocEvents {
@internal @internal
abstract interface class AppsBlocStates { abstract interface class AppsBlocStates {
BehaviorSubject<Result<List<CoreNavigationEntry>>> get apps; BehaviorSubject<Result<List<core.NavigationEntry>>> get apps;
BehaviorSubject<Result<Iterable<AppImplementation>>> get appImplementations; BehaviorSubject<Result<Iterable<AppImplementation>>> get appImplementations;
@ -182,7 +183,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
BehaviorSubject(); BehaviorSubject();
@override @override
BehaviorSubject<Result<List<CoreNavigationEntry>>> apps = BehaviorSubject(); BehaviorSubject<Result<List<core.NavigationEntry>>> apps = BehaviorSubject();
@override @override
BehaviorSubject<Result<NotificationsAppInterface?>> notificationsAppImplementation = BehaviorSubject(); BehaviorSubject<Result<NotificationsAppInterface?>> notificationsAppImplementation = BehaviorSubject();

6
packages/neon/neon/lib/src/blocs/capabilities.dart

@ -5,7 +5,7 @@ import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/bloc/result.dart'; import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/utils/request_manager.dart'; import 'package:neon/src/utils/request_manager.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@internal @internal
@ -13,7 +13,7 @@ abstract interface class CapabilitiesBlocEvents {}
@internal @internal
abstract interface class CapabilitiesBlocStates { abstract interface class CapabilitiesBlocStates {
BehaviorSubject<Result<CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data>> get capabilities; BehaviorSubject<Result<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data>> get capabilities;
} }
@internal @internal
@ -33,7 +33,7 @@ class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents
} }
@override @override
BehaviorSubject<Result<CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data>> capabilities = BehaviorSubject(); BehaviorSubject<Result<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data>> capabilities = BehaviorSubject();
@override @override
Future<void> refresh() async { Future<void> refresh() async {

1
packages/neon/neon/lib/src/blocs/login_check_account.dart

@ -7,6 +7,7 @@ import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/utils/user_agent.dart'; import 'package:neon/src/utils/user_agent.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/provisioning_api.dart' as provisioning_api;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@internal @internal

5
packages/neon/neon/lib/src/blocs/login_check_server_status.dart

@ -5,6 +5,7 @@ import 'package:meta/meta.dart';
import 'package:neon/src/bloc/bloc.dart'; import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/bloc/result.dart'; import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/utils/user_agent.dart'; import 'package:neon/src/utils/user_agent.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@ -14,7 +15,7 @@ abstract interface class LoginCheckServerStatusBlocEvents {}
@internal @internal
abstract interface class LoginCheckServerStatusBlocStates { abstract interface class LoginCheckServerStatusBlocStates {
/// Contains the current server connection state /// Contains the current server connection state
BehaviorSubject<Result<CoreStatus>> get state; BehaviorSubject<Result<core.Status>> get state;
} }
@internal @internal
@ -34,7 +35,7 @@ class LoginCheckServerStatusBloc extends InteractiveBloc
} }
@override @override
BehaviorSubject<Result<CoreStatus>> state = BehaviorSubject(); BehaviorSubject<Result<core.Status>> state = BehaviorSubject();
@override @override
Future<void> refresh() async { Future<void> refresh() async {

11
packages/neon/neon/lib/src/blocs/login_flow.dart

@ -5,6 +5,7 @@ import 'package:meta/meta.dart';
import 'package:neon/src/bloc/bloc.dart'; import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/bloc/result.dart'; import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/utils/user_agent.dart'; import 'package:neon/src/utils/user_agent.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@ -13,9 +14,9 @@ abstract interface class LoginFlowBlocEvents {}
@internal @internal
abstract interface class LoginFlowBlocStates { abstract interface class LoginFlowBlocStates {
BehaviorSubject<Result<CoreLoginFlowV2>> get init; BehaviorSubject<Result<core.LoginFlowV2>> get init;
Stream<CoreLoginFlowV2Credentials> get result; Stream<core.LoginFlowV2Credentials> get result;
} }
@internal @internal
@ -29,7 +30,7 @@ class LoginFlowBloc extends InteractiveBloc implements LoginFlowBlocEvents, Logi
serverURL, serverURL,
userAgentOverride: neonUserAgent, userAgentOverride: neonUserAgent,
); );
final _resultController = StreamController<CoreLoginFlowV2Credentials>(); final _resultController = StreamController<core.LoginFlowV2Credentials>();
Timer? _pollTimer; Timer? _pollTimer;
@ -43,10 +44,10 @@ class LoginFlowBloc extends InteractiveBloc implements LoginFlowBlocEvents, Logi
} }
@override @override
BehaviorSubject<Result<CoreLoginFlowV2>> init = BehaviorSubject(); BehaviorSubject<Result<core.LoginFlowV2>> init = BehaviorSubject();
@override @override
late Stream<CoreLoginFlowV2Credentials> result = _resultController.stream.asBroadcastStream(); late Stream<core.LoginFlowV2Credentials> result = _resultController.stream.asBroadcastStream();
@override @override
Future<void> refresh() async { Future<void> refresh() async {

2
packages/neon/neon/lib/src/blocs/next_push.dart

@ -6,7 +6,7 @@ import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/blocs/accounts.dart'; import 'package:neon/src/blocs/accounts.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/utils/global_options.dart'; import 'package:neon/src/utils/global_options.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/uppush.dart' as uppush;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@internal @internal

4
packages/neon/neon/lib/src/blocs/push_notifications.dart

@ -10,7 +10,7 @@ import 'package:neon/src/platform/platform.dart';
import 'package:neon/src/settings/models/storage.dart'; import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/global_options.dart'; import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/push_utils.dart'; import 'package:neon/src/utils/push_utils.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/notifications.dart' as notifications;
import 'package:unifiedpush/unifiedpush.dart'; import 'package:unifiedpush/unifiedpush.dart';
@internal @internal
@ -80,7 +80,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
debugPrint('Registering account $instance for push notifications on $endpoint'); debugPrint('Registering account $instance for push notifications on $endpoint');
final subscription = await account.client.notifications.push.registerDevice( final subscription = await account.client.notifications.push.registerDevice(
pushTokenHash: generatePushTokenHash(endpoint), pushTokenHash: notifications.generatePushTokenHash(endpoint),
devicePublicKey: keypair.publicKey.toFormattedPEM(), devicePublicKey: keypair.publicKey.toFormattedPEM(),
proxyServer: '$endpoint#', // This is a hack to make the Nextcloud server directly push to the endpoint proxyServer: '$endpoint#', // This is a hack to make the Nextcloud server directly push to the endpoint
); );

24
packages/neon/neon/lib/src/blocs/unified_search.dart

@ -7,7 +7,7 @@ import 'package:neon/models.dart';
import 'package:neon/src/bloc/bloc.dart'; import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/bloc/result.dart'; import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/blocs/apps.dart'; import 'package:neon/src/blocs/apps.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@internal @internal
@ -23,7 +23,7 @@ abstract interface class UnifiedSearchBlocEvents {
abstract interface class UnifiedSearchBlocStates { abstract interface class UnifiedSearchBlocStates {
BehaviorSubject<bool> get enabled; BehaviorSubject<bool> get enabled;
BehaviorSubject<Result<Map<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>?>> get results; BehaviorSubject<Result<Map<core.UnifiedSearchProvider, Result<core.UnifiedSearchResult>>?>> get results;
} }
@internal @internal
@ -47,7 +47,7 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
BehaviorSubject<bool> enabled = BehaviorSubject.seeded(false); BehaviorSubject<bool> enabled = BehaviorSubject.seeded(false);
@override @override
BehaviorSubject<Result<Map<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>?>> results = BehaviorSubject<Result<Map<core.UnifiedSearchProvider, Result<core.UnifiedSearchResult>>?>> results =
BehaviorSubject.seeded(Result.success(null)); BehaviorSubject.seeded(Result.success(null));
@override @override
@ -103,15 +103,15 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
} }
} }
Iterable<MapEntry<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>> _getLoadingProviders( Iterable<MapEntry<core.UnifiedSearchProvider, Result<core.UnifiedSearchResult>>> _getLoadingProviders(
final Iterable<CoreUnifiedSearchProvider> providers, final Iterable<core.UnifiedSearchProvider> providers,
) sync* { ) sync* {
for (final provider in providers) { for (final provider in providers) {
yield MapEntry(provider, Result.loading()); yield MapEntry(provider, Result.loading());
} }
} }
Future<void> _searchProvider(final CoreUnifiedSearchProvider provider) async { Future<void> _searchProvider(final core.UnifiedSearchProvider provider) async {
_updateResults(provider, Result.loading()); _updateResults(provider, Result.loading());
try { try {
final response = await _account.client.core.unifiedSearch.search( final response = await _account.client.core.unifiedSearch.search(
@ -126,7 +126,7 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
} }
} }
void _updateResults(final CoreUnifiedSearchProvider provider, final Result<CoreUnifiedSearchResult> result) => void _updateResults(final core.UnifiedSearchProvider provider, final Result<core.UnifiedSearchResult> result) =>
results.add( results.add(
Result.success( Result.success(
Map.fromEntries( Map.fromEntries(
@ -138,8 +138,8 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
), ),
); );
Iterable<MapEntry<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>> _sortResults( Iterable<MapEntry<core.UnifiedSearchProvider, Result<core.UnifiedSearchResult>>> _sortResults(
final Map<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>> results, final Map<core.UnifiedSearchProvider, Result<core.UnifiedSearchResult>> results,
) sync* { ) sync* {
final activeApp = _appsBloc.activeApp.value; final activeApp = _appsBloc.activeApp.value;
@ -152,12 +152,12 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
.sorted((final a, final b) => _sortEntriesCount(a.value, b.value)); .sorted((final a, final b) => _sortEntriesCount(a.value, b.value));
} }
bool _providerMatchesApp(final CoreUnifiedSearchProvider provider, final AppImplementation app) => bool _providerMatchesApp(final core.UnifiedSearchProvider provider, final AppImplementation app) =>
provider.id == app.id || provider.id.startsWith('${app.id}_'); provider.id == app.id || provider.id.startsWith('${app.id}_');
bool _hasEntries(final Result<CoreUnifiedSearchResult> result) => bool _hasEntries(final Result<core.UnifiedSearchResult> result) =>
!result.hasData || result.requireData.entries.isNotEmpty; !result.hasData || result.requireData.entries.isNotEmpty;
int _sortEntriesCount(final Result<CoreUnifiedSearchResult> a, final Result<CoreUnifiedSearchResult> b) => int _sortEntriesCount(final Result<core.UnifiedSearchResult> a, final Result<core.UnifiedSearchResult> b) =>
(b.data?.entries.length ?? 0).compareTo(a.data?.entries.length ?? 0); (b.data?.entries.length ?? 0).compareTo(a.data?.entries.length ?? 0);
} }

6
packages/neon/neon/lib/src/blocs/user_details.dart

@ -5,7 +5,7 @@ import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/bloc/result.dart'; import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/utils/request_manager.dart'; import 'package:neon/src/utils/request_manager.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/provisioning_api.dart' as provisioning_api;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
@internal @internal
@ -13,7 +13,7 @@ abstract interface class UserDetailsBlocEvents {}
@internal @internal
abstract interface class UserDetailsBlocStates { abstract interface class UserDetailsBlocStates {
BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails; BehaviorSubject<Result<provisioning_api.UserDetails>> get userDetails;
} }
@internal @internal
@ -33,7 +33,7 @@ class UserDetailsBloc extends InteractiveBloc implements UserDetailsBlocEvents,
} }
@override @override
BehaviorSubject<Result<ProvisioningApiUserDetails>> userDetails = BehaviorSubject(); BehaviorSubject<Result<provisioning_api.UserDetails>> userDetails = BehaviorSubject();
@override @override
Future<void> refresh() async { Future<void> refresh() async {

13
packages/neon/neon/lib/src/blocs/user_statuses.dart

@ -8,6 +8,7 @@ import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/blocs/timer.dart'; import 'package:neon/src/blocs/timer.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/user_status.dart' as user_status;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
@ -18,7 +19,7 @@ abstract interface class UserStatusesBlocEvents {
@internal @internal
abstract interface class UserStatusesBlocStates { abstract interface class UserStatusesBlocStates {
BehaviorSubject<Map<String, Result<UserStatusPublicInterface?>>> get statuses; BehaviorSubject<Map<String, Result<user_status.PublicInterface?>>> get statuses;
} }
@internal @internal
@ -41,7 +42,7 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
} }
@override @override
BehaviorSubject<Map<String, Result<UserStatusPublicInterface?>>> statuses = BehaviorSubject(); BehaviorSubject<Map<String, Result<user_status.PublicInterface?>>> statuses = BehaviorSubject();
@override @override
Future<void> refresh() async { Future<void> refresh() async {
@ -59,7 +60,7 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
try { try {
_updateStatus(username, Result.loading()); _updateStatus(username, Result.loading());
UserStatusPublicInterface? data; user_status.PublicInterface? data;
if (_account.username == username) { if (_account.username == username) {
var isAway = false; var isAway = false;
@ -98,10 +99,10 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
} }
} }
Map<String, Result<UserStatusPublicInterface?>> get _statuses => Map<String, Result<user_status.PublicInterface?>> get _statuses =>
statuses.valueOrNull ?? <String, Result<UserStatusPublicInterface?>>{}; statuses.valueOrNull ?? <String, Result<user_status.PublicInterface?>>{};
void _updateStatus(final String username, final Result<UserStatusPublicInterface?> result) { void _updateStatus(final String username, final Result<user_status.PublicInterface?> result) {
statuses.add({ statuses.add({
..._statuses, ..._statuses,
username: result, username: result,

4
packages/neon/neon/lib/src/models/app_implementation.dart

@ -14,7 +14,7 @@ import 'package:neon/src/settings/models/options_collection.dart';
import 'package:neon/src/settings/models/storage.dart'; import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/provider.dart'; import 'package:neon/src/utils/provider.dart';
import 'package:neon/src/widgets/drawer_destination.dart'; import 'package:neon/src/widgets/drawer_destination.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:vector_graphics/vector_graphics.dart'; import 'package:vector_graphics/vector_graphics.dart';
@ -45,7 +45,7 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
/// The first value of the record is the supported status and the second value is the supported minimum version. /// The first value of the record is the supported status and the second value is the supported minimum version.
FutureOr<(bool? supported, String? minimumVersion)> isSupported( FutureOr<(bool? supported, String? minimumVersion)> isSupported(
final Account account, final Account account,
final CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
); );
final blocsCache = AccountCache<T>(); final blocsCache = AccountCache<T>();

4
packages/neon/neon/lib/src/models/push_notification.dart

@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/notifications.dart' show DecryptedSubject;
part 'push_notification.g.dart'; part 'push_notification.g.dart';
@ -24,5 +24,5 @@ class PushNotification {
final String type; final String type;
final NotificationsDecryptedSubject subject; final DecryptedSubject subject;
} }

2
packages/neon/neon/lib/src/models/push_notification.g.dart

@ -10,7 +10,7 @@ PushNotification _$PushNotificationFromJson(Map<String, dynamic> json) => PushNo
accountID: json['accountID'] as String, accountID: json['accountID'] as String,
priority: json['priority'] as String, priority: json['priority'] as String,
type: json['type'] as String, type: json['type'] as String,
subject: NotificationsDecryptedSubject.fromJson(json['subject'] as Map<String, dynamic>), subject: DecryptedSubject.fromJson(json['subject'] as Map<String, dynamic>),
); );
Map<String, dynamic> _$PushNotificationToJson(PushNotification instance) => <String, dynamic>{ Map<String, dynamic> _$PushNotificationToJson(PushNotification instance) => <String, dynamic>{

4
packages/neon/neon/lib/src/pages/account_settings.dart

@ -15,7 +15,7 @@ import 'package:neon/src/theme/dialog.dart';
import 'package:neon/src/utils/confirmation_dialog.dart'; import 'package:neon/src/utils/confirmation_dialog.dart';
import 'package:neon/src/widgets/error.dart'; import 'package:neon/src/widgets/error.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/provisioning_api.dart' as provisioning_api;
@internal @internal
class AccountSettingsPage extends StatelessWidget { class AccountSettingsPage extends StatelessWidget {
@ -77,7 +77,7 @@ class AccountSettingsPage extends StatelessWidget {
], ],
); );
final body = ResultBuilder<ProvisioningApiUserDetails>.behaviorSubject( final body = ResultBuilder<provisioning_api.UserDetails>.behaviorSubject(
stream: userDetailsBloc.userDetails, stream: userDetailsBloc.userDetails,
builder: (final context, final userDetails) => SettingsList( builder: (final context, final userDetails) => SettingsList(
categories: [ categories: [

2
packages/neon/neon/lib/src/pages/home.dart

@ -16,7 +16,7 @@ import 'package:neon/src/widgets/app_bar.dart';
import 'package:neon/src/widgets/drawer.dart'; import 'package:neon/src/widgets/drawer.dart';
import 'package:neon/src/widgets/error.dart'; import 'package:neon/src/widgets/error.dart';
import 'package:neon/src/widgets/unified_search_results.dart'; import 'package:neon/src/widgets/unified_search_results.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@internal @internal

6
packages/neon/neon/lib/src/pages/login_check_server_status.dart

@ -8,7 +8,7 @@ import 'package:neon/src/router.dart';
import 'package:neon/src/theme/dialog.dart'; import 'package:neon/src/theme/dialog.dart';
import 'package:neon/src/widgets/error.dart'; import 'package:neon/src/widgets/error.dart';
import 'package:neon/src/widgets/validation_tile.dart'; import 'package:neon/src/widgets/validation_tile.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
@internal @internal
class LoginCheckServerStatusPage extends StatefulWidget { class LoginCheckServerStatusPage extends StatefulWidget {
@ -105,7 +105,7 @@ class _LoginCheckServerStatusPageState extends State<LoginCheckServerStatusPage>
} }
} }
Widget _buildServerVersionTile(final Result<CoreStatus> result) { Widget _buildServerVersionTile(final Result<core.Status> result) {
if (result.hasError) { if (result.hasError) {
return NeonValidationTile( return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingServerVersion, title: AppLocalizations.of(context).loginCheckingServerVersion,
@ -133,7 +133,7 @@ class _LoginCheckServerStatusPageState extends State<LoginCheckServerStatusPage>
); );
} }
Widget _buildMaintenanceModeTile(final Result<CoreStatus> result) { Widget _buildMaintenanceModeTile(final Result<core.Status> result) {
if (result.hasError) { if (result.hasError) {
return NeonValidationTile( return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingMaintenanceMode, title: AppLocalizations.of(context).loginCheckingMaintenanceMode,

4
packages/neon/neon/lib/src/theme/theme.dart

@ -3,7 +3,7 @@ import 'package:meta/meta.dart';
import 'package:neon/src/theme/colors.dart'; import 'package:neon/src/theme/colors.dart';
import 'package:neon/src/theme/neon.dart'; import 'package:neon/src/theme/neon.dart';
import 'package:neon/src/utils/hex_color.dart'; import 'package:neon/src/utils/hex_color.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
@internal @internal
@immutable @immutable
@ -16,7 +16,7 @@ class AppTheme {
this.appThemes, this.appThemes,
}) : keepOriginalAccentColor = nextcloudTheme == null || keepOriginalAccentColor; }) : keepOriginalAccentColor = nextcloudTheme == null || keepOriginalAccentColor;
final CoreThemingPublicCapabilities_Theming? nextcloudTheme; final core.ThemingPublicCapabilities_Theming? nextcloudTheme;
final bool keepOriginalAccentColor; final bool keepOriginalAccentColor;
final bool oledAsDark; final bool oledAsDark;
final Iterable<ThemeExtension>? appThemes; final Iterable<ThemeExtension>? appThemes;

14
packages/neon/neon/lib/src/utils/push_utils.dart

@ -16,26 +16,26 @@ import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/theme/colors.dart'; import 'package:neon/src/theme/colors.dart';
import 'package:neon/src/utils/global.dart'; import 'package:neon/src/utils/global.dart';
import 'package:neon/src/utils/localizations.dart'; import 'package:neon/src/utils/localizations.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/notifications.dart' as notifications;
@internal @internal
@immutable @immutable
class PushUtils { class PushUtils {
const PushUtils._(); const PushUtils._();
static Future<RSAKeypair> loadRSAKeypair() async { static Future<notifications.RSAKeypair> loadRSAKeypair() async {
const storage = AppStorage(StorageKeys.notifications); const storage = AppStorage(StorageKeys.notifications);
const keyDevicePrivateKey = 'device-private-key'; const keyDevicePrivateKey = 'device-private-key';
late RSAKeypair keypair; late notifications.RSAKeypair keypair;
if (!storage.containsKey(keyDevicePrivateKey) || (storage.getString(keyDevicePrivateKey)?.isEmpty ?? true)) { if (!storage.containsKey(keyDevicePrivateKey) || (storage.getString(keyDevicePrivateKey)?.isEmpty ?? true)) {
debugPrint('Generating RSA keys for push notifications'); debugPrint('Generating RSA keys for push notifications');
// The key size has to be 2048, other sizes are not accepted by Nextcloud (at the moment at least) // The key size has to be 2048, other sizes are not accepted by Nextcloud (at the moment at least)
// ignore: avoid_redundant_argument_values // ignore: avoid_redundant_argument_values
keypair = RSAKeypair.fromRandom(keySize: 2048); keypair = notifications.RSAKeypair.fromRandom(keySize: 2048);
await storage.setString(keyDevicePrivateKey, keypair.privateKey.toPEM()); await storage.setString(keyDevicePrivateKey, keypair.privateKey.toPEM());
} else { } else {
keypair = RSAKeypair(RSAPrivateKey.fromPEM(storage.getString(keyDevicePrivateKey)!)); keypair = notifications.RSAKeypair(notifications.RSAPrivateKey.fromPEM(storage.getString(keyDevicePrivateKey)!));
} }
return keypair; return keypair;
@ -82,7 +82,7 @@ class PushUtils {
accountID: instance, accountID: instance,
priority: data['priority']! as String, priority: data['priority']! as String,
type: data['type']! as String, type: data['type']! as String,
subject: decryptPushNotificationSubject(keypair.privateKey, data['subject']! as String), subject: notifications.decryptPushNotificationSubject(keypair.privateKey, data['subject']! as String),
); );
if (pushNotification.subject.delete ?? false) { if (pushNotification.subject.delete ?? false) {
@ -97,7 +97,7 @@ class PushUtils {
final accounts = loadAccounts(); final accounts = loadAccounts();
Account? account; Account? account;
NotificationsNotification? notification; notifications.Notification? notification;
AndroidBitmap<Object>? largeIconBitmap; AndroidBitmap<Object>? largeIconBitmap;
try { try {
account = accounts.tryFind(instance); account = accounts.tryFind(instance);

4
packages/neon/neon/lib/src/widgets/account_tile.dart

@ -7,7 +7,7 @@ import 'package:neon/src/utils/provider.dart';
import 'package:neon/src/widgets/error.dart'; import 'package:neon/src/widgets/error.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:neon/src/widgets/user_avatar.dart'; import 'package:neon/src/widgets/user_avatar.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/provisioning_api.dart' as provisioning_api;
@internal @internal
class NeonAccountTile extends StatelessWidget { class NeonAccountTile extends StatelessWidget {
@ -50,7 +50,7 @@ class NeonAccountTile extends StatelessWidget {
showStatus: showStatus, showStatus: showStatus,
), ),
trailing: trailing, trailing: trailing,
title: ResultBuilder<ProvisioningApiUserDetails>.behaviorSubject( title: ResultBuilder<provisioning_api.UserDetails>.behaviorSubject(
stream: userDetailsBloc.userDetails, stream: userDetailsBloc.userDetails,
builder: (final context, final userDetails) => Row( builder: (final context, final userDetails) => Row(
children: [ children: [

4
packages/neon/neon/lib/src/widgets/drawer.dart

@ -13,7 +13,7 @@ import 'package:neon/src/widgets/drawer_destination.dart';
import 'package:neon/src/widgets/error.dart'; import 'package:neon/src/widgets/error.dart';
import 'package:neon/src/widgets/image.dart'; import 'package:neon/src/widgets/image.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
@internal @internal
class NeonDrawer extends StatelessWidget { class NeonDrawer extends StatelessWidget {
@ -121,7 +121,7 @@ class NeonDrawerHeader extends StatelessWidget {
final accountsBloc = NeonProvider.of<AccountsBloc>(context); final accountsBloc = NeonProvider.of<AccountsBloc>(context);
final capabilitiesBloc = accountsBloc.activeCapabilitiesBloc; final capabilitiesBloc = accountsBloc.activeCapabilitiesBloc;
final branding = ResultBuilder<CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data>.behaviorSubject( final branding = ResultBuilder<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data>.behaviorSubject(
stream: capabilitiesBloc.capabilities, stream: capabilitiesBloc.capabilities,
builder: (final context, final capabilities) { builder: (final context, final capabilities) {
if (!capabilities.hasData) { if (!capabilities.hasData) {

12
packages/neon/neon/lib/src/widgets/unified_search_results.dart

@ -14,7 +14,7 @@ import 'package:neon/src/widgets/image.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:neon/src/widgets/list_view.dart'; import 'package:neon/src/widgets/list_view.dart';
import 'package:neon/src/widgets/server_icon.dart'; import 'package:neon/src/widgets/server_icon.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
@internal @internal
class NeonUnifiedSearchResults extends StatelessWidget { class NeonUnifiedSearchResults extends StatelessWidget {
@ -59,10 +59,10 @@ class NeonUnifiedSearchResults extends StatelessWidget {
final BuildContext context, final BuildContext context,
final AccountsBloc accountsBloc, final AccountsBloc accountsBloc,
final UnifiedSearchBloc bloc, final UnifiedSearchBloc bloc,
final CoreUnifiedSearchProvider provider, final core.UnifiedSearchProvider provider,
final Result<CoreUnifiedSearchResult> result, final Result<core.UnifiedSearchResult> result,
) { ) {
final entries = result.data?.entries ?? <CoreUnifiedSearchResultEntry>[]; final entries = result.data?.entries ?? <core.UnifiedSearchResultEntry>[];
return Card( return Card(
child: Container( child: Container(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(10),
@ -108,7 +108,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
); );
} }
Widget _buildThumbnail(final BuildContext context, final Account account, final CoreUnifiedSearchResultEntry entry) { Widget _buildThumbnail(final BuildContext context, final Account account, final core.UnifiedSearchResultEntry entry) {
if (entry.thumbnailUrl.isNotEmpty) { if (entry.thumbnailUrl.isNotEmpty) {
return NeonCachedImage.url( return NeonCachedImage.url(
size: const Size.square(largeIconSize), size: const Size.square(largeIconSize),
@ -125,7 +125,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
Widget? _buildFallbackIcon( Widget? _buildFallbackIcon(
final BuildContext context, final BuildContext context,
final Account account, final Account account,
final CoreUnifiedSearchResultEntry entry, final core.UnifiedSearchResultEntry entry,
) { ) {
if (entry.icon.startsWith('/')) { if (entry.icon.startsWith('/')) {
return NeonCachedImage.url( return NeonCachedImage.url(

5
packages/neon/neon/lib/src/widgets/user_avatar.dart

@ -9,7 +9,8 @@ import 'package:neon/src/theme/sizes.dart';
import 'package:neon/src/utils/provider.dart'; import 'package:neon/src/utils/provider.dart';
import 'package:neon/src/widgets/image.dart'; import 'package:neon/src/widgets/image.dart';
import 'package:neon/src/widgets/server_icon.dart'; import 'package:neon/src/widgets/server_icon.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/user_status.dart' as user_status;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
class NeonUserAvatar extends StatefulWidget { class NeonUserAvatar extends StatefulWidget {
@ -91,7 +92,7 @@ class _UserAvatarState extends State<NeonUserAvatar> {
}, },
); );
Widget _userStatusIconBuilder(final BuildContext context, final Result<UserStatusPublicInterface?> result) { Widget _userStatusIconBuilder(final BuildContext context, final Result<user_status.PublicInterface?> result) {
final hasEmoji = result.data?.icon != null; final hasEmoji = result.data?.icon != null;
final scaledSize = size / (hasEmoji ? 2 : 2.5); final scaledSize = size / (hasEmoji ? 2 : 2.5);

5
packages/neon/neon_files/lib/neon_files.dart

@ -13,7 +13,6 @@ import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:neon/blocs.dart'; import 'package:neon/blocs.dart';
import 'package:neon/models.dart'; import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/platform.dart'; import 'package:neon/platform.dart';
import 'package:neon/settings.dart'; import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart'; import 'package:neon/sort_box.dart';
@ -23,6 +22,8 @@ import 'package:neon/widgets.dart';
import 'package:neon_files/l10n/localizations.dart'; import 'package:neon_files/l10n/localizations.dart';
import 'package:neon_files/routes.dart'; import 'package:neon_files/routes.dart';
import 'package:neon_files/widgets/file_list_tile.dart'; import 'package:neon_files/widgets/file_list_tile.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -75,7 +76,7 @@ class FilesApp extends AppImplementation<FilesBloc, FilesAppSpecificOptions> {
@override @override
(bool? supported, String? minimumVersion) isSupported( (bool? supported, String? minimumVersion) isSupported(
final Account account, final Account account,
final CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) => ) =>
const (null, null); const (null, null);
} }

2
packages/neon/neon_files/lib/routes.dart

@ -1,8 +1,8 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/utils.dart'; import 'package:neon/utils.dart';
import 'package:neon_files/neon_files.dart'; import 'package:neon_files/neon_files.dart';
import 'package:nextcloud/nextcloud.dart';
part 'routes.g.dart'; part 'routes.g.dart';

4
packages/neon/neon_files/pubspec.yaml

@ -26,6 +26,10 @@ dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon/neon path: packages/neon/neon
nextcloud:
git:
url: https://github.com/nextcloud/neon
path: packages/nextcloud
open_file: ^3.0.0 open_file: ^3.0.0
path: ^1.0.0 path: ^1.0.0
path_provider: ^2.0.0 path_provider: ^2.0.0

2
packages/neon/neon_news/lib/blocs/article.dart

@ -19,7 +19,7 @@ abstract interface class NewsArticleBlocStates {
class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents, NewsArticleBlocStates { class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents, NewsArticleBlocStates {
NewsArticleBloc( NewsArticleBloc(
this._newsArticlesBloc, this._newsArticlesBloc,
final NewsArticle article, final news.Article article,
) { ) {
_id = article.id; _id = article.id;
unread.add(article.unread); unread.add(article.unread);

34
packages/neon/neon_news/lib/blocs/articles.dart

@ -14,17 +14,17 @@ enum ListType {
abstract interface class NewsArticlesBlocEvents { abstract interface class NewsArticlesBlocEvents {
void setFilterType(final FilterType type); void setFilterType(final FilterType type);
void markArticleAsRead(final NewsArticle article); void markArticleAsRead(final news.Article article);
void markArticleAsUnread(final NewsArticle article); void markArticleAsUnread(final news.Article article);
void starArticle(final NewsArticle article); void starArticle(final news.Article article);
void unstarArticle(final NewsArticle article); void unstarArticle(final news.Article article);
} }
abstract interface class NewsArticlesBlocStates { abstract interface class NewsArticlesBlocStates {
BehaviorSubject<Result<List<NewsArticle>>> get articles; BehaviorSubject<Result<List<news.Article>>> get articles;
BehaviorSubject<FilterType> get filterType; BehaviorSubject<FilterType> get filterType;
} }
@ -69,7 +69,7 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
BehaviorSubject<Result<List<NewsArticle>>> articles = BehaviorSubject<Result<List<NewsArticle>>>(); BehaviorSubject<Result<List<news.Article>>> articles = BehaviorSubject<Result<List<news.Article>>>();
@override @override
BehaviorSubject<FilterType> filterType = BehaviorSubject<FilterType>(); BehaviorSubject<FilterType> filterType = BehaviorSubject<FilterType>();
@ -87,7 +87,7 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
// https://github.com/nextcloud/news/blob/master/docs/api/api-v1-2.md#get-items // https://github.com/nextcloud/news/blob/master/docs/api/api-v1-2.md#get-items
// https://github.com/nextcloud/news/blob/48ee5ce4d135da20079961a62ae37958d6a6b628/lib/Db/ListType.php#L21 // https://github.com/nextcloud/news/blob/48ee5ce4d135da20079961a62ae37958d6a6b628/lib/Db/ListType.php#L21
late final NewsListType type; late final news.ListType type;
bool? getRead; bool? getRead;
if (listType != null) { if (listType != null) {
switch (filterType.value) { switch (filterType.value) {
@ -101,21 +101,21 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
switch (listType) { switch (listType) {
case ListType.feed: case ListType.feed:
type = NewsListType.feed; type = news.ListType.feed;
case ListType.folder: case ListType.folder:
type = NewsListType.folder; type = news.ListType.folder;
case null: case null:
switch (filterType.value) { switch (filterType.value) {
case FilterType.starred: case FilterType.starred:
type = NewsListType.starred; type = news.ListType.starred;
case FilterType.all: case FilterType.all:
type = NewsListType.allItems; type = news.ListType.allItems;
case FilterType.unread: case FilterType.unread:
type = NewsListType.unread; type = news.ListType.unread;
} }
} }
await RequestManager.instance.wrapNextcloud<List<NewsArticle>, NewsListArticles, void>( await RequestManager.instance.wrapNextcloud<List<news.Article>, news.ListArticles, void>(
account.id, account.id,
'news-articles-${type.index}-$id-$getRead', 'news-articles-${type.index}-$id-$getRead',
articles, articles,
@ -129,12 +129,12 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
void markArticleAsRead(final NewsArticle article) { void markArticleAsRead(final news.Article article) {
wrapAction(() async => account.client.news.markArticleAsRead(itemId: article.id)); wrapAction(() async => account.client.news.markArticleAsRead(itemId: article.id));
} }
@override @override
void markArticleAsUnread(final NewsArticle article) { void markArticleAsUnread(final news.Article article) {
wrapAction(() async => account.client.news.markArticleAsUnread(itemId: article.id)); wrapAction(() async => account.client.news.markArticleAsUnread(itemId: article.id));
} }
@ -144,12 +144,12 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
void starArticle(final NewsArticle article) { void starArticle(final news.Article article) {
wrapAction(() async => account.client.news.starArticle(itemId: article.id)); wrapAction(() async => account.client.news.starArticle(itemId: article.id));
} }
@override @override
void unstarArticle(final NewsArticle article) { void unstarArticle(final news.Article article) {
wrapAction(() async => account.client.news.unstarArticle(itemId: article.id)); wrapAction(() async => account.client.news.unstarArticle(itemId: article.id));
} }
} }

22
packages/neon/neon_news/lib/blocs/news.dart

@ -21,9 +21,9 @@ abstract interface class NewsBlocEvents {
} }
abstract interface class NewsBlocStates { abstract interface class NewsBlocStates {
BehaviorSubject<Result<List<NewsFolder>>> get folders; BehaviorSubject<Result<List<news.Folder>>> get folders;
BehaviorSubject<Result<List<NewsFeed>>> get feeds; BehaviorSubject<Result<List<news.Feed>>> get feeds;
BehaviorSubject<int> get unreadCounter; BehaviorSubject<int> get unreadCounter;
} }
@ -75,16 +75,16 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
BehaviorSubject<Result<List<NewsFeed>>> feeds = BehaviorSubject<Result<List<NewsFeed>>>(); BehaviorSubject<Result<List<news.Feed>>> feeds = BehaviorSubject<Result<List<news.Feed>>>();
@override @override
BehaviorSubject<Result<List<NewsFolder>>> folders = BehaviorSubject<Result<List<NewsFolder>>>(); BehaviorSubject<Result<List<news.Folder>>> folders = BehaviorSubject<Result<List<news.Folder>>>();
@override @override
BehaviorSubject<int> unreadCounter = BehaviorSubject<int>(); BehaviorSubject<int> unreadCounter = BehaviorSubject<int>();
@override @override
late BehaviorSubject<Result<List<NewsArticle>>> articles = mainArticlesBloc.articles; late BehaviorSubject<Result<List<news.Article>>> articles = mainArticlesBloc.articles;
@override @override
late BehaviorSubject<FilterType> filterType = mainArticlesBloc.filterType; late BehaviorSubject<FilterType> filterType = mainArticlesBloc.filterType;
@ -92,14 +92,14 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
@override @override
Future<void> refresh() async { Future<void> refresh() async {
await Future.wait([ await Future.wait([
RequestManager.instance.wrapNextcloud<List<NewsFolder>, NewsListFolders, void>( RequestManager.instance.wrapNextcloud<List<news.Folder>, news.ListFolders, void>(
account.id, account.id,
'news-folders', 'news-folders',
folders, folders,
account.client.news.listFoldersRaw(), account.client.news.listFoldersRaw(),
(final response) => response.body.folders.toList(), (final response) => response.body.folders.toList(),
), ),
RequestManager.instance.wrapNextcloud<List<NewsFeed>, NewsListFeeds, void>( RequestManager.instance.wrapNextcloud<List<news.Feed>, news.ListFeeds, void>(
account.id, account.id,
'news-feeds', 'news-feeds',
feeds, feeds,
@ -161,12 +161,12 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
void markArticleAsRead(final NewsArticle article) { void markArticleAsRead(final news.Article article) {
mainArticlesBloc.markArticleAsRead(article); mainArticlesBloc.markArticleAsRead(article);
} }
@override @override
void markArticleAsUnread(final NewsArticle article) { void markArticleAsUnread(final news.Article article) {
mainArticlesBloc.markArticleAsUnread(article); mainArticlesBloc.markArticleAsUnread(article);
} }
@ -176,12 +176,12 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
void starArticle(final NewsArticle article) { void starArticle(final news.Article article) {
mainArticlesBloc.starArticle(article); mainArticlesBloc.starArticle(article);
} }
@override @override
void unstarArticle(final NewsArticle article) { void unstarArticle(final news.Article article) {
mainArticlesBloc.unstarArticle(article); mainArticlesBloc.unstarArticle(article);
} }

4
packages/neon/neon_news/lib/dialogs/add_feed.dart

@ -18,7 +18,7 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
final controller = TextEditingController(); final controller = TextEditingController();
NewsFolder? folder; news.Folder? folder;
void submit() { void submit() {
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {
@ -49,7 +49,7 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NewsFolder>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<news.Folder>>.behaviorSubject(
stream: widget.bloc.folders, stream: widget.bloc.folders,
builder: (final context, final folders) => NeonDialog( builder: (final context, final folders) => NeonDialog(
title: Text(AppLocalizations.of(context).feedAdd), title: Text(AppLocalizations.of(context).feedAdd),

2
packages/neon/neon_news/lib/dialogs/feed_show_url.dart

@ -6,7 +6,7 @@ class NewsFeedShowURLDialog extends StatefulWidget {
super.key, super.key,
}); });
final NewsFeed feed; final news.Feed feed;
@override @override
State<NewsFeedShowURLDialog> createState() => _NewsFeedShowURLDialogState(); State<NewsFeedShowURLDialog> createState() => _NewsFeedShowURLDialogState();

2
packages/neon/neon_news/lib/dialogs/feed_update_error.dart

@ -6,7 +6,7 @@ class NewsFeedUpdateErrorDialog extends StatefulWidget {
super.key, super.key,
}); });
final NewsFeed feed; final news.Feed feed;
@override @override
State<NewsFeedUpdateErrorDialog> createState() => _NewsFeedUpdateErrorDialogState(); State<NewsFeedUpdateErrorDialog> createState() => _NewsFeedUpdateErrorDialogState();

6
packages/neon/neon_news/lib/dialogs/move_feed.dart

@ -7,8 +7,8 @@ class NewsMoveFeedDialog extends StatefulWidget {
super.key, super.key,
}); });
final List<NewsFolder> folders; final List<news.Folder> folders;
final NewsFeed feed; final news.Feed feed;
@override @override
State<NewsMoveFeedDialog> createState() => _NewsMoveFeedDialogState(); State<NewsMoveFeedDialog> createState() => _NewsMoveFeedDialogState();
@ -17,7 +17,7 @@ class NewsMoveFeedDialog extends StatefulWidget {
class _NewsMoveFeedDialogState extends State<NewsMoveFeedDialog> { class _NewsMoveFeedDialogState extends State<NewsMoveFeedDialog> {
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
NewsFolder? folder; news.Folder? folder;
void submit() { void submit() {
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {

6
packages/neon/neon_news/lib/neon_news.dart

@ -12,7 +12,6 @@ import 'package:html/dom.dart' as html_dom;
import 'package:html/parser.dart' as html_parser; import 'package:html/parser.dart' as html_parser;
import 'package:neon/blocs.dart'; import 'package:neon/blocs.dart';
import 'package:neon/models.dart'; import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/platform.dart'; import 'package:neon/platform.dart';
import 'package:neon/settings.dart'; import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart'; import 'package:neon/sort_box.dart';
@ -21,6 +20,9 @@ import 'package:neon/utils.dart';
import 'package:neon/widgets.dart'; import 'package:neon/widgets.dart';
import 'package:neon_news/l10n/localizations.dart'; import 'package:neon_news/l10n/localizations.dart';
import 'package:neon_news/routes.dart'; import 'package:neon_news/routes.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/news.dart' as news;
import 'package:nextcloud/nextcloud.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
@ -85,7 +87,7 @@ class NewsApp extends AppImplementation<NewsBloc, NewsAppSpecificOptions> {
@override @override
Future<(bool? supported, String? minimumVersion)> isSupported( Future<(bool? supported, String? minimumVersion)> isSupported(
final Account account, final Account account,
final CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) => ) =>
account.client.news.isSupported(); account.client.news.isSupported();
} }

2
packages/neon/neon_news/lib/pages/feed.dart

@ -8,7 +8,7 @@ class NewsFeedPage extends StatelessWidget {
}); });
final NewsBloc bloc; final NewsBloc bloc;
final NewsFeed feed; final news.Feed feed;
@override @override
Widget build(final BuildContext context) => Scaffold( Widget build(final BuildContext context) => Scaffold(

2
packages/neon/neon_news/lib/pages/folder.dart

@ -8,7 +8,7 @@ class NewsFolderPage extends StatelessWidget {
}); });
final NewsBloc bloc; final NewsBloc bloc;
final NewsFolder folder; final news.Folder folder;
@override @override
Widget build(final BuildContext context) => Scaffold( Widget build(final BuildContext context) => Scaffold(

2
packages/neon/neon_news/lib/routes.dart

@ -1,8 +1,8 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/utils.dart'; import 'package:neon/utils.dart';
import 'package:neon_news/neon_news.dart'; import 'package:neon_news/neon_news.dart';
import 'package:nextcloud/nextcloud.dart';
part 'routes.g.dart'; part 'routes.g.dart';

2
packages/neon/neon_news/lib/sort/articles.dart

@ -1,6 +1,6 @@
part of '../neon_news.dart'; part of '../neon_news.dart';
final articlesSortBox = SortBox<ArticlesSortProperty, NewsArticle>( final articlesSortBox = SortBox<ArticlesSortProperty, news.Article>(
{ {
ArticlesSortProperty.publishDate: (final article) => article.pubDate, ArticlesSortProperty.publishDate: (final article) => article.pubDate,
ArticlesSortProperty.alphabetical: (final article) => article.title.toLowerCase(), ArticlesSortProperty.alphabetical: (final article) => article.title.toLowerCase(),

2
packages/neon/neon_news/lib/sort/feeds.dart

@ -1,6 +1,6 @@
part of '../neon_news.dart'; part of '../neon_news.dart';
final feedsSortBox = SortBox<FeedsSortProperty, NewsFeed>( final feedsSortBox = SortBox<FeedsSortProperty, news.Feed>(
{ {
FeedsSortProperty.alphabetical: (final feed) => feed.title.toLowerCase(), FeedsSortProperty.alphabetical: (final feed) => feed.title.toLowerCase(),
FeedsSortProperty.unreadCount: (final feed) => feed.unreadCount ?? 0, FeedsSortProperty.unreadCount: (final feed) => feed.unreadCount ?? 0,

2
packages/neon/neon_news/lib/sort/folders.dart

@ -15,4 +15,4 @@ final foldersSortBox = SortBox<FoldersSortProperty, FolderFeedsWrapper>(
}, },
); );
typedef FolderFeedsWrapper = (NewsFolder folder, int feedCount, int unreadCount); typedef FolderFeedsWrapper = (news.Folder folder, int feedCount, int unreadCount);

10
packages/neon/neon_news/lib/widgets/articles_view.dart

@ -25,11 +25,11 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NewsFeed>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<news.Feed>>.behaviorSubject(
stream: widget.newsBloc.feeds, stream: widget.newsBloc.feeds,
builder: (final context, final feeds) => ResultBuilder<List<NewsArticle>>.behaviorSubject( builder: (final context, final feeds) => ResultBuilder<List<news.Article>>.behaviorSubject(
stream: widget.bloc.articles, stream: widget.bloc.articles,
builder: (final context, final articles) => SortBoxBuilder<ArticlesSortProperty, NewsArticle>( builder: (final context, final articles) => SortBoxBuilder<ArticlesSortProperty, news.Article>(
sortBox: articlesSortBox, sortBox: articlesSortBox,
sortProperty: widget.newsBloc.options.articlesSortPropertyOption, sortProperty: widget.newsBloc.options.articlesSortPropertyOption,
sortBoxOrder: widget.newsBloc.options.articlesSortBoxOrderOption, sortBoxOrder: widget.newsBloc.options.articlesSortBoxOrderOption,
@ -101,8 +101,8 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
Widget _buildArticle( Widget _buildArticle(
final BuildContext context, final BuildContext context,
final NewsArticle article, final news.Article article,
final NewsFeed feed, final news.Feed feed,
) => ) =>
ListTile( ListTile(
title: Row( title: Row(

2
packages/neon/neon_news/lib/widgets/feed_icon.dart

@ -8,7 +8,7 @@ class NewsFeedIcon extends StatelessWidget {
super.key, super.key,
}); });
final NewsFeed feed; final news.Feed feed;
final double size; final double size;
final BorderRadius? borderRadius; final BorderRadius? borderRadius;

10
packages/neon/neon_news/lib/widgets/feeds_view.dart

@ -11,11 +11,11 @@ class NewsFeedsView extends StatelessWidget {
final int? folderID; final int? folderID;
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NewsFolder>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<news.Folder>>.behaviorSubject(
stream: bloc.folders, stream: bloc.folders,
builder: (final context, final folders) => ResultBuilder<List<NewsFeed>>.behaviorSubject( builder: (final context, final folders) => ResultBuilder<List<news.Feed>>.behaviorSubject(
stream: bloc.feeds, stream: bloc.feeds,
builder: (final context, final feeds) => SortBoxBuilder<FeedsSortProperty, NewsFeed>( builder: (final context, final feeds) => SortBoxBuilder<FeedsSortProperty, news.Feed>(
sortBox: feedsSortBox, sortBox: feedsSortBox,
sortProperty: bloc.options.feedsSortPropertyOption, sortProperty: bloc.options.feedsSortPropertyOption,
sortBoxOrder: bloc.options.feedsSortBoxOrderOption, sortBoxOrder: bloc.options.feedsSortBoxOrderOption,
@ -40,8 +40,8 @@ class NewsFeedsView extends StatelessWidget {
Widget _buildFeed( Widget _buildFeed(
final BuildContext context, final BuildContext context,
final NewsFeed feed, final news.Feed feed,
final List<NewsFolder> folders, final List<news.Folder> folders,
) => ) =>
ListTile( ListTile(
title: Text( title: Text(

10
packages/neon/neon_news/lib/widgets/folder_select.dart

@ -8,12 +8,12 @@ class NewsFolderSelect extends StatelessWidget {
super.key, super.key,
}); });
final List<NewsFolder> folders; final List<news.Folder> folders;
final ValueChanged<NewsFolder?> onChanged; final ValueChanged<news.Folder?> onChanged;
final NewsFolder? value; final news.Folder? value;
@override @override
Widget build(final BuildContext context) => DropdownButtonFormField<NewsFolder>( Widget build(final BuildContext context) => DropdownButtonFormField<news.Folder>(
decoration: InputDecoration( decoration: InputDecoration(
hintText: AppLocalizations.of(context).folder, hintText: AppLocalizations.of(context).folder,
), ),
@ -23,7 +23,7 @@ class NewsFolderSelect extends StatelessWidget {
child: Text(AppLocalizations.of(context).folderRoot), child: Text(AppLocalizations.of(context).folderRoot),
), ),
...folders.map( ...folders.map(
(final f) => DropdownMenuItem<NewsFolder>( (final f) => DropdownMenuItem<news.Folder>(
value: f, value: f,
child: Text(f.name), child: Text(f.name),
), ),

2
packages/neon/neon_news/lib/widgets/folder_view.dart

@ -8,7 +8,7 @@ class NewsFolderView extends StatefulWidget {
}); });
final NewsBloc bloc; final NewsBloc bloc;
final NewsFolder folder; final news.Folder folder;
@override @override
State<NewsFolderView> createState() => _NewsFolderViewState(); State<NewsFolderView> createState() => _NewsFolderViewState();

4
packages/neon/neon_news/lib/widgets/folders_view.dart

@ -9,9 +9,9 @@ class NewsFoldersView extends StatelessWidget {
final NewsBloc bloc; final NewsBloc bloc;
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NewsFolder>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<news.Folder>>.behaviorSubject(
stream: bloc.folders, stream: bloc.folders,
builder: (final context, final folders) => ResultBuilder<List<NewsFeed>>.behaviorSubject( builder: (final context, final folders) => ResultBuilder<List<news.Feed>>.behaviorSubject(
stream: bloc.feeds, stream: bloc.feeds,
builder: (final context, final feeds) => SortBoxBuilder<FoldersSortProperty, FolderFeedsWrapper>( builder: (final context, final feeds) => SortBoxBuilder<FoldersSortProperty, FolderFeedsWrapper>(
sortBox: foldersSortBox, sortBox: foldersSortBox,

4
packages/neon/neon_news/pubspec.yaml

@ -20,6 +20,10 @@ dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon/neon path: packages/neon/neon
nextcloud:
git:
url: https://github.com/nextcloud/neon
path: packages/nextcloud
rxdart: ^0.27.0 rxdart: ^0.27.0
share_plus: ^7.0.0 share_plus: ^7.0.0
url_launcher: ^6.0.0 url_launcher: ^6.0.0

6
packages/neon/neon_notes/lib/blocs/note.dart

@ -15,7 +15,7 @@ abstract interface class NotesNoteBlocStates {
class NotesNoteBloc extends InteractiveBloc implements NotesNoteBlocEvents, NotesNoteBlocStates { class NotesNoteBloc extends InteractiveBloc implements NotesNoteBlocEvents, NotesNoteBlocStates {
NotesNoteBloc( NotesNoteBloc(
this._notesBloc, this._notesBloc,
final NotesNote note, final notes.Note note,
) { ) {
_emitNote(note); _emitNote(note);
id = note.id; id = note.id;
@ -23,13 +23,13 @@ class NotesNoteBloc extends InteractiveBloc implements NotesNoteBlocEvents, Note
initialTitle = note.title; initialTitle = note.title;
} }
void _emitNote(final NotesNote note) { void _emitNote(final notes.Note note) {
category.add(note.category); category.add(note.category);
_etag = note.etag; _etag = note.etag;
} }
// ignore: avoid_void_async // ignore: avoid_void_async
void _wrapAction(final Future<DynamiteResponse<NotesNote, dynamic>> Function(String etag) call) async { void _wrapAction(final Future<DynamiteResponse<notes.Note, dynamic>> Function(String etag) call) async {
await _updateQueue.add(() async { await _updateQueue.add(() async {
try { try {
final response = await call(_etag); final response = await call(_etag);

12
packages/neon/neon_notes/lib/blocs/notes.dart

@ -19,7 +19,7 @@ abstract interface class NotesBlocEvents {
} }
abstract interface class NotesBlocStates { abstract interface class NotesBlocStates {
BehaviorSubject<Result<List<NotesNote>>> get notes; BehaviorSubject<Result<List<notes.Note>>> get notesList;
} }
class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocStates { class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocStates {
@ -35,21 +35,21 @@ class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocSta
@override @override
void dispose() { void dispose() {
unawaited(notes.close()); unawaited(notesList.close());
super.dispose(); super.dispose();
} }
@override @override
BehaviorSubject<Result<List<NotesNote>>> notes = BehaviorSubject<Result<List<NotesNote>>>(); BehaviorSubject<Result<List<notes.Note>>> notesList = BehaviorSubject<Result<List<notes.Note>>>();
@override @override
Future<void> refresh() async { Future<void> refresh() async {
await RequestManager.instance.wrapNextcloud<List<NotesNote>, BuiltList<NotesNote>, void>( await RequestManager.instance.wrapNextcloud<List<notes.Note>, BuiltList<notes.Note>, void>(
account.id, account.id,
'notes-notes', 'notes-notes',
notes, notesList,
account.client.notes.getNotesRaw(), account.client.notes.getNotesRaw(),
(final response) => List<NotesNote>.from(response.body), (final response) => List<notes.Note>.from(response.body),
); );
} }

4
packages/neon/neon_notes/lib/dialogs/create_note.dart

@ -32,8 +32,8 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NotesNote>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: widget.bloc.notes, stream: widget.bloc.notesList,
builder: (final context, final notes) => NeonDialog( builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).noteCreate), title: Text(AppLocalizations.of(context).noteCreate),
children: [ children: [

4
packages/neon/neon_notes/lib/dialogs/select_category.dart

@ -26,8 +26,8 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NotesNote>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: widget.bloc.notes, stream: widget.bloc.notesList,
builder: (final context, final notes) => NeonDialog( builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).category), title: Text(AppLocalizations.of(context).category),
children: [ children: [

6
packages/neon/neon_notes/lib/neon_notes.dart

@ -11,7 +11,6 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/blocs.dart'; import 'package:neon/blocs.dart';
import 'package:neon/models.dart'; import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/settings.dart'; import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart'; import 'package:neon/sort_box.dart';
import 'package:neon/theme.dart'; import 'package:neon/theme.dart';
@ -19,6 +18,9 @@ import 'package:neon/utils.dart';
import 'package:neon/widgets.dart'; import 'package:neon/widgets.dart';
import 'package:neon_notes/l10n/localizations.dart'; import 'package:neon_notes/l10n/localizations.dart';
import 'package:neon_notes/routes.dart'; import 'package:neon_notes/routes.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/notes.dart' as notes;
import 'package:queue/queue.dart'; import 'package:queue/queue.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
@ -71,7 +73,7 @@ class NotesApp extends AppImplementation<NotesBloc, NotesAppSpecificOptions> {
@override @override
(bool? supported, String? minimumVersion) isSupported( (bool? supported, String? minimumVersion) isSupported(
final Account account, final Account account,
final CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) { ) {
final (supported, minimumVersion) = account.client.notes.isSupported(capabilities); final (supported, minimumVersion) = account.client.notes.isSupported(capabilities);
return (supported, minimumVersion.toString()); return (supported, minimumVersion.toString());

2
packages/neon/neon_notes/lib/routes.dart

@ -1,8 +1,8 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/utils.dart'; import 'package:neon/utils.dart';
import 'package:neon_notes/neon_notes.dart'; import 'package:neon_notes/neon_notes.dart';
import 'package:nextcloud/nextcloud.dart';
part 'routes.g.dart'; part 'routes.g.dart';

2
packages/neon/neon_notes/lib/sort/notes.dart

@ -1,6 +1,6 @@
part of '../neon_notes.dart'; part of '../neon_notes.dart';
final notesSortBox = SortBox<NotesSortProperty, NotesNote>( final notesSortBox = SortBox<NotesSortProperty, notes.Note>(
{ {
NotesSortProperty.alphabetical: (final note) => note.title.toLowerCase(), NotesSortProperty.alphabetical: (final note) => note.title.toLowerCase(),
NotesSortProperty.lastModified: (final note) => note.modified, NotesSortProperty.lastModified: (final note) => note.modified,

4
packages/neon/neon_notes/lib/widgets/categories_view.dart

@ -9,8 +9,8 @@ class NotesCategoriesView extends StatelessWidget {
final NotesBloc bloc; final NotesBloc bloc;
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NotesNote>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: bloc.notes, stream: bloc.notesList,
builder: (final context, final notes) => SortBoxBuilder<CategoriesSortProperty, NoteCategory>( builder: (final context, final notes) => SortBoxBuilder<CategoriesSortProperty, NoteCategory>(
sortBox: categoriesSortBox, sortBox: categoriesSortBox,
sortProperty: bloc.options.categoriesSortPropertyOption, sortProperty: bloc.options.categoriesSortPropertyOption,

16
packages/neon/neon_notes/lib/widgets/notes_view.dart

@ -11,20 +11,22 @@ class NotesView extends StatelessWidget {
final String? category; final String? category;
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NotesNote>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: bloc.notes, stream: bloc.notesList,
builder: (final context, final notes) => SortBoxBuilder<NotesSortProperty, NotesNote>( builder: (final context, final notesList) => SortBoxBuilder<NotesSortProperty, notes.Note>(
sortBox: notesSortBox, sortBox: notesSortBox,
presort: const { presort: const {
(NotesSortProperty.favorite, SortBoxOrder.ascending), (NotesSortProperty.favorite, SortBoxOrder.ascending),
}, },
sortProperty: bloc.options.notesSortPropertyOption, sortProperty: bloc.options.notesSortPropertyOption,
sortBoxOrder: bloc.options.notesSortBoxOrderOption, sortBoxOrder: bloc.options.notesSortBoxOrderOption,
input: category != null ? notes.data?.where((final note) => note.category == category).toList() : notes.data, input: category != null
? notesList.data?.where((final note) => note.category == category).toList()
: notesList.data,
builder: (final context, final sorted) => NeonListView( builder: (final context, final sorted) => NeonListView(
scrollKey: 'notes-notes', scrollKey: 'notes-notes',
isLoading: notes.isLoading, isLoading: notesList.isLoading,
error: notes.error, error: notesList.error,
onRefresh: bloc.refresh, onRefresh: bloc.refresh,
itemCount: sorted.length, itemCount: sorted.length,
itemBuilder: (final context, final index) => _buildNote(context, sorted[index]), itemBuilder: (final context, final index) => _buildNote(context, sorted[index]),
@ -34,7 +36,7 @@ class NotesView extends StatelessWidget {
Widget _buildNote( Widget _buildNote(
final BuildContext context, final BuildContext context,
final NotesNote note, final notes.Note note,
) => ) =>
ListTile( ListTile(
title: Text(note.title), title: Text(note.title),

4
packages/neon/neon_notes/pubspec.yaml

@ -21,6 +21,10 @@ dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon/neon path: packages/neon/neon
nextcloud:
git:
url: https://github.com/nextcloud/neon
path: packages/nextcloud
queue: ^3.0.0 queue: ^3.0.0
rxdart: ^0.27.0 rxdart: ^0.27.0
url_launcher: ^6.0.0 url_launcher: ^6.0.0

16
packages/neon/neon_notifications/lib/blocs/notifications.dart

@ -7,7 +7,7 @@ abstract interface class NotificationsBlocEvents {
} }
abstract interface class NotificationsBlocStates { abstract interface class NotificationsBlocStates {
BehaviorSubject<Result<List<NotificationsNotification>>> get notifications; BehaviorSubject<Result<List<notifications.Notification>>> get notificationsList;
BehaviorSubject<int> get unreadCounter; BehaviorSubject<int> get unreadCounter;
} }
@ -18,7 +18,7 @@ class NotificationsBloc extends InteractiveBloc
this.options, this.options,
this._account, this._account,
) { ) {
notifications.listen((final result) { notificationsList.listen((final result) {
if (result.hasData) { if (result.hasData) {
unreadCounter.add(result.requireData.length); unreadCounter.add(result.requireData.length);
} }
@ -36,25 +36,25 @@ class NotificationsBloc extends InteractiveBloc
@override @override
void dispose() { void dispose() {
_timer.cancel(); _timer.cancel();
unawaited(notifications.close()); unawaited(notificationsList.close());
unawaited(unreadCounter.close()); unawaited(unreadCounter.close());
super.dispose(); super.dispose();
} }
@override @override
BehaviorSubject<Result<List<NotificationsNotification>>> notifications = BehaviorSubject<Result<List<notifications.Notification>>> notificationsList =
BehaviorSubject<Result<List<NotificationsNotification>>>(); BehaviorSubject<Result<List<notifications.Notification>>>();
@override @override
BehaviorSubject<int> unreadCounter = BehaviorSubject<int>(); BehaviorSubject<int> unreadCounter = BehaviorSubject<int>();
@override @override
Future<void> refresh() async { Future<void> refresh() async {
await RequestManager.instance.wrapNextcloud<List<NotificationsNotification>, await RequestManager.instance.wrapNextcloud<List<notifications.Notification>,
NotificationsEndpointListNotificationsResponseApplicationJson, void>( notifications.EndpointListNotificationsResponseApplicationJson, void>(
_account.id, _account.id,
'notifications-notifications', 'notifications-notifications',
notifications, notificationsList,
_account.client.notifications.endpoint.listNotificationsRaw(), _account.client.notifications.endpoint.listNotificationsRaw(),
(final response) => response.body.ocs.data.toList(), (final response) => response.body.ocs.data.toList(),
); );

6
packages/neon/neon_notifications/lib/neon_notifications.dart

@ -7,13 +7,15 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/blocs.dart'; import 'package:neon/blocs.dart';
import 'package:neon/models.dart'; import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/settings.dart'; import 'package:neon/settings.dart';
import 'package:neon/theme.dart'; import 'package:neon/theme.dart';
import 'package:neon/utils.dart'; import 'package:neon/utils.dart';
import 'package:neon/widgets.dart'; import 'package:neon/widgets.dart';
import 'package:neon_notifications/l10n/localizations.dart'; import 'package:neon_notifications/l10n/localizations.dart';
import 'package:neon_notifications/routes.dart'; import 'package:neon_notifications/routes.dart';
import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/notifications.dart' as notifications;
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
part 'blocs/notifications.dart'; part 'blocs/notifications.dart';
@ -56,7 +58,7 @@ class NotificationsApp extends AppImplementation<NotificationsBloc, Notification
@override @override
(bool? supported, String? minimumVersion) isSupported( (bool? supported, String? minimumVersion) isSupported(
final Account account, final Account account,
final CoreOcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities,
) => ) =>
const (null, null); const (null, null);
} }

6
packages/neon/neon_notifications/lib/pages/main.dart

@ -24,8 +24,8 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<List<NotificationsNotification>>.behaviorSubject( Widget build(final BuildContext context) => ResultBuilder<List<notifications.Notification>>.behaviorSubject(
stream: bloc.notifications, stream: bloc.notificationsList,
builder: (final context, final notifications) => Scaffold( builder: (final context, final notifications) => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
floatingActionButton: StreamBuilder<int>( floatingActionButton: StreamBuilder<int>(
@ -52,7 +52,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
Widget _buildNotification( Widget _buildNotification(
final BuildContext context, final BuildContext context,
final NotificationsNotification notification, final notifications.Notification notification,
) { ) {
final app = NeonProvider.of<Iterable<AppImplementation>>(context).tryFind(notification.app); final app = NeonProvider.of<Iterable<AppImplementation>>(context).tryFind(notification.app);

2
packages/neon/neon_notifications/lib/routes.dart

@ -1,8 +1,8 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/utils.dart'; import 'package:neon/utils.dart';
import 'package:neon_notifications/neon_notifications.dart'; import 'package:neon_notifications/neon_notifications.dart';
import 'package:nextcloud/nextcloud.dart';
part 'routes.g.dart'; part 'routes.g.dart';

4
packages/neon/neon_notifications/pubspec.yaml

@ -18,6 +18,10 @@ dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon/neon path: packages/neon/neon
nextcloud:
git:
url: https://github.com/nextcloud/neon
path: packages/nextcloud
rxdart: ^0.27.0 rxdart: ^0.27.0
dev_dependencies: dev_dependencies:

Loading…
Cancel
Save