Browse Source

dynamite,nextcloud,neon: Prefix every object

pull/167/head
jld3103 2 years ago
parent
commit
66614bb2e2
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 103
      packages/dynamite/lib/src/openapi_builder.dart
  2. 2
      packages/neon/lib/src/app.dart
  3. 2
      packages/neon/lib/src/apps/news/blocs/article.dart
  4. 22
      packages/neon/lib/src/apps/news/blocs/articles.dart
  5. 22
      packages/neon/lib/src/apps/news/blocs/news.dart
  6. 4
      packages/neon/lib/src/apps/news/dialogs/add_feed.dart
  7. 2
      packages/neon/lib/src/apps/news/dialogs/feed_show_url.dart
  8. 2
      packages/neon/lib/src/apps/news/dialogs/feed_update_error.dart
  9. 6
      packages/neon/lib/src/apps/news/dialogs/move_feed.dart
  10. 2
      packages/neon/lib/src/apps/news/pages/feed.dart
  11. 2
      packages/neon/lib/src/apps/news/pages/folder.dart
  12. 2
      packages/neon/lib/src/apps/news/sort/articles.dart
  13. 2
      packages/neon/lib/src/apps/news/sort/feeds.dart
  14. 6
      packages/neon/lib/src/apps/news/sort/folders.dart
  15. 12
      packages/neon/lib/src/apps/news/widgets/articles_view.dart
  16. 2
      packages/neon/lib/src/apps/news/widgets/feed_icon.dart
  17. 12
      packages/neon/lib/src/apps/news/widgets/feeds_view.dart
  18. 10
      packages/neon/lib/src/apps/news/widgets/folder_select.dart
  19. 2
      packages/neon/lib/src/apps/news/widgets/folder_view.dart
  20. 4
      packages/neon/lib/src/apps/news/widgets/folders_view.dart
  21. 6
      packages/neon/lib/src/apps/notes/blocs/note.dart
  22. 6
      packages/neon/lib/src/apps/notes/blocs/notes.dart
  23. 2
      packages/neon/lib/src/apps/notes/dialogs/create_note.dart
  24. 2
      packages/neon/lib/src/apps/notes/dialogs/select_category.dart
  25. 2
      packages/neon/lib/src/apps/notes/sort/notes.dart
  26. 2
      packages/neon/lib/src/apps/notes/utils/exception_handler.dart
  27. 2
      packages/neon/lib/src/apps/notes/widgets/categories_view.dart
  28. 10
      packages/neon/lib/src/apps/notes/widgets/notes_view.dart
  29. 9
      packages/neon/lib/src/apps/notifications/blocs/notifications.dart
  30. 7
      packages/neon/lib/src/apps/notifications/pages/main.dart
  31. 4
      packages/neon/lib/src/blocs/apps.dart
  32. 6
      packages/neon/lib/src/blocs/capabilities.dart
  33. 10
      packages/neon/lib/src/blocs/login.dart
  34. 2
      packages/neon/lib/src/blocs/push_notifications.dart
  35. 8
      packages/neon/lib/src/blocs/user_details.dart
  36. 8
      packages/neon/lib/src/blocs/user_status.dart
  37. 2
      packages/neon/lib/src/models/push_notification_with_account.dart
  38. 2
      packages/neon/lib/src/models/push_notification_with_account.g.dart
  39. 2
      packages/neon/lib/src/pages/account_settings.dart
  40. 4
      packages/neon/lib/src/utils/push_utils.dart
  41. 2
      packages/neon/lib/src/utils/theme.dart
  42. 13
      packages/neon/lib/src/widgets/account_avatar.dart
  43. 2
      packages/neon/lib/src/widgets/account_tile.dart
  44. 2
      packages/neon/lib/src/widgets/exception.dart
  45. 3
      packages/nextcloud/lib/nextcloud.dart
  46. 4
      packages/nextcloud/lib/src/client.dart
  47. 12
      packages/nextcloud/lib/src/helpers.dart
  48. 3603
      packages/nextcloud/lib/src/nextcloud.openapi.dart
  49. 1225
      packages/nextcloud/lib/src/nextcloud.openapi.g.dart
  50. 10
      packages/nextcloud/lib/src/version_supported.dart
  51. 4
      packages/nextcloud/lib/src/webdav/client.dart
  52. 4
      packages/nextcloud/test/news.dart
  53. 12
      packages/nextcloud/test/notes.dart
  54. 38
      packages/nextcloud/test/user_status.dart
  55. 4
      packages/nextcloud/test/webdav.dart

103
packages/dynamite/lib/src/openapi_builder.dart

@ -22,6 +22,7 @@ class OpenAPIBuilder implements Builder {
await buildStep.readAsString(inputId), await buildStep.readAsString(inputId),
) as Map<String, dynamic>, ) as Map<String, dynamic>,
); );
final prefix = _toDartName(spec.info.title, uppercaseFirstCharacter: true);
if (spec.version != '3.1.0') { if (spec.version != '3.1.0') {
throw Exception('Only OpenAPI 3.1.0 is supported'); throw Exception('Only OpenAPI 3.1.0 is supported');
} }
@ -34,7 +35,7 @@ class OpenAPIBuilder implements Builder {
]; ];
final hasAnySecurity = spec.security?.isNotEmpty ?? false; final hasAnySecurity = spec.security?.isNotEmpty ?? false;
final state = State(); final state = State(prefix);
final output = <String>[ final output = <String>[
"import 'dart:convert';", "import 'dart:convert';",
"import 'dart:io';", "import 'dart:io';",
@ -49,7 +50,7 @@ class OpenAPIBuilder implements Builder {
'', '',
Extension( Extension(
(final b) => b (final b) => b
..name = 'HttpClientResponseBody' ..name = '${prefix}HttpClientResponseBody'
..on = refer('HttpClientResponse') ..on = refer('HttpClientResponse')
..methods.addAll([ ..methods.addAll([
Method( Method(
@ -83,7 +84,7 @@ class OpenAPIBuilder implements Builder {
).accept(emitter).toString(), ).accept(emitter).toString(),
Class( Class(
(final b) => b (final b) => b
..name = 'Response' ..name = '${prefix}Response'
..types.addAll([ ..types.addAll([
refer('T'), refer('T'),
refer('U'), refer('U'),
@ -123,8 +124,8 @@ class OpenAPIBuilder implements Builder {
..returns = refer('String') ..returns = refer('String')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..lambda = true ..lambda = true
..body = const Code( ..body = Code(
r"'Response(data: $data, headers: $headers)'", "'${prefix}Response(data: \$data, headers: \$headers)'",
), ),
), ),
), ),
@ -181,7 +182,7 @@ class OpenAPIBuilder implements Builder {
).accept(emitter).toString(), ).accept(emitter).toString(),
Class( Class(
(final b) => b (final b) => b
..name = 'ApiException' ..name = '${prefix}ApiException'
..extend = refer('_Response') ..extend = refer('_Response')
..implements.add(refer('Exception')) ..implements.add(refer('Exception'))
..constructors.addAll( ..constructors.addAll(
@ -210,7 +211,7 @@ class OpenAPIBuilder implements Builder {
..type = refer('_Response'), ..type = refer('_Response'),
), ),
) )
..body = const Code('ApiException(response.statusCode, response.headers, response.body,)'), ..body = Code('${prefix}ApiException(response.statusCode, response.headers, response.body,)'),
), ),
], ],
) )
@ -221,8 +222,8 @@ class OpenAPIBuilder implements Builder {
..returns = refer('String') ..returns = refer('String')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..lambda = true ..lambda = true
..body = const Code( ..body = Code(
r"'ApiException(statusCode: ${super.statusCode}, headers: ${super.headers}, body: ${utf8.decode(super.body)})'", "'${prefix}ApiException(statusCode: \${super.statusCode}, headers: \${super.headers}, body: \${utf8.decode(super.body)})'",
), ),
), ),
), ),
@ -230,7 +231,7 @@ class OpenAPIBuilder implements Builder {
if (hasAnySecurity) ...[ if (hasAnySecurity) ...[
Class( Class(
(final b) => b (final b) => b
..name = 'Authentication' ..name = '${prefix}Authentication'
..abstract = true ..abstract = true
..methods.add( ..methods.add(
Method( Method(
@ -257,8 +258,8 @@ class OpenAPIBuilder implements Builder {
(final b) { (final b) {
final fields = ['username', 'password']; final fields = ['username', 'password'];
b b
..name = 'HttpBasicAuthentication' ..name = '${prefix}HttpBasicAuthentication'
..extend = refer('Authentication') ..extend = refer('${prefix}Authentication')
..constructors.add( ..constructors.add(
Constructor( Constructor(
(final b) => b (final b) => b
@ -373,7 +374,7 @@ class OpenAPIBuilder implements Builder {
Field( Field(
(final b) => b (final b) => b
..name = 'authentication' ..name = 'authentication'
..type = refer('Authentication?') ..type = refer('${prefix}Authentication?')
..modifier = FieldModifier.final$, ..modifier = FieldModifier.final$,
), ),
], ],
@ -445,8 +446,8 @@ class OpenAPIBuilder implements Builder {
..name = _toDartName(tag.name) ..name = _toDartName(tag.name)
..lambda = true ..lambda = true
..type = MethodType.getter ..type = MethodType.getter
..returns = refer(_clientName(tag)) ..returns = refer('$prefix${_clientName(tag)}')
..body = Code('${_clientName(tag)}(this)'), ..body = Code('$prefix${_clientName(tag)}(this)'),
), ),
], ],
], ],
@ -512,7 +513,7 @@ class OpenAPIBuilder implements Builder {
Field( Field(
(final b) => b (final b) => b
..name = 'rootClient' ..name = 'rootClient'
..type = refer('Client') ..type = refer('${prefix}Client')
..modifier = FieldModifier.final$, ..modifier = FieldModifier.final$,
), ),
) )
@ -529,7 +530,7 @@ class OpenAPIBuilder implements Builder {
); );
} }
b b
..name = isRootClient ? 'Client' : _clientName(tag) ..name = '$prefix${isRootClient ? 'Client' : _clientName(tag)}'
..methods.addAll( ..methods.addAll(
[ [
for (final path in paths.keys) ...[ for (final path in paths.keys) ...[
@ -654,6 +655,7 @@ class OpenAPIBuilder implements Builder {
_toDartName('$methodName-request-$mimeType', uppercaseFirstCharacter: true), _toDartName('$methodName-request-$mimeType', uppercaseFirstCharacter: true),
mediaType.schema!, mediaType.schema!,
); );
final parameterName = _toDartName(result.name.replaceFirst(prefix, ''));
switch (mimeType) { switch (mimeType) {
case 'application/json': case 'application/json':
case 'application/x-www-form-urlencoded': case 'application/x-www-form-urlencoded':
@ -664,7 +666,7 @@ class OpenAPIBuilder implements Builder {
b.optionalParameters.add( b.optionalParameters.add(
Parameter( Parameter(
(final b) => b (final b) => b
..name = _toDartName(result.name) ..name = parameterName
..type = refer(_makeNullable(result.name, nullable)) ..type = refer(_makeNullable(result.name, nullable))
..named = true ..named = true
..required = operation.requestBody!.required ?? false, ..required = operation.requestBody!.required ?? false,
@ -672,10 +674,10 @@ class OpenAPIBuilder implements Builder {
); );
if (nullable) { if (nullable) {
code.write('if (${_toDartName(result.name)} != null) {'); code.write('if ($parameterName != null) {');
} }
code.write( code.write(
'body = Uint8List.fromList(utf8.encode(${result.encode(result.serialize(_toDartName(result.name)), mimeType: mimeType)}));', 'body = Uint8List.fromList(utf8.encode(${result.encode(result.serialize(parameterName), mimeType: mimeType)}));',
); );
if (nullable) { if (nullable) {
code.write('}'); code.write('}');
@ -805,7 +807,9 @@ class OpenAPIBuilder implements Builder {
code.write('}'); code.write('}');
} }
code.write('throw ApiException.fromResponse(response); // coverage:ignore-line\n'); code.write(
'throw ${prefix}ApiException.fromResponse(response); // coverage:ignore-line\n',
);
} else { } else {
b.returns = refer('Future'); b.returns = refer('Future');
} }
@ -1018,6 +1022,9 @@ bool _isParameterNullable(final bool? required, final dynamic default_) => !(req
String _valueToEscapedValue(final String type, final dynamic value) => type == 'String' ? "'$value'" : value.toString(); String _valueToEscapedValue(final String type, final dynamic value) => type == 'String' ? "'$value'" : value.toString();
class State { class State {
State(this.prefix);
final String prefix;
final resolvedTypes = <String>[]; final resolvedTypes = <String>[];
final registeredJsonObjects = <String>[]; final registeredJsonObjects = <String>[];
final output = <Spec>[]; final output = <Spec>[];
@ -1032,14 +1039,14 @@ TypeResult resolveObject(
required final Map<String, Map<String, String>>? extraJsonKeyValues, required final Map<String, Map<String, String>>? extraJsonKeyValues,
final bool fromJsonString = false, final bool fromJsonString = false,
}) { }) {
if (!state.resolvedTypes.contains(identifier)) { if (!state.resolvedTypes.contains('${state.prefix}$identifier')) {
state.resolvedTypes.add(identifier); state.resolvedTypes.add('${state.prefix}$identifier');
state.registeredJsonObjects.add(identifier); state.registeredJsonObjects.add('${state.prefix}$identifier');
state.output.add( state.output.add(
Class( Class(
(final b) { (final b) {
b b
..name = identifier ..name = '${state.prefix}$identifier'
..docs.addAll([ ..docs.addAll([
if (schema.description != null && schema.description!.isNotEmpty) ...[ if (schema.description != null && schema.description!.isNotEmpty) ...[
'/// ${schema.description!}', '/// ${schema.description!}',
@ -1102,7 +1109,7 @@ TypeResult resolveObject(
..type = refer('Map<String, dynamic>'), ..type = refer('Map<String, dynamic>'),
), ),
) )
..body = Code('_\$${identifier}FromJson(json)'), ..body = Code('_\$${state.prefix}${identifier}FromJson(json)'),
), ),
Constructor( Constructor(
(final b) => b (final b) => b
@ -1116,7 +1123,7 @@ TypeResult resolveObject(
..type = refer('String'), ..type = refer('String'),
), ),
) )
..body = Code('$identifier.fromJson(json.decode(data) as Map<String, dynamic>)'), ..body = Code('${state.prefix}$identifier.fromJson(json.decode(data) as Map<String, dynamic>)'),
), ),
], ],
) )
@ -1126,7 +1133,7 @@ TypeResult resolveObject(
..name = 'toJson' ..name = 'toJson'
..returns = refer('Map<String, dynamic>') ..returns = refer('Map<String, dynamic>')
..lambda = true ..lambda = true
..body = Code('_\$${identifier}ToJson(this)'), ..body = Code('_\$${state.prefix}${identifier}ToJson(this)'),
), ),
Method( Method(
(final b) => b (final b) => b
@ -1138,7 +1145,7 @@ TypeResult resolveObject(
Parameter( Parameter(
(final b) => b (final b) => b
..name = 'data' ..name = 'data'
..type = refer(_makeNullable(identifier, true)), ..type = refer(_makeNullable('${state.prefix}$identifier', true)),
), ),
) )
..body = const Code('data == null ? null : json.encode(data.toJson())'), ..body = const Code('data == null ? null : json.encode(data.toJson())'),
@ -1180,7 +1187,7 @@ TypeResult resolveObject(
var fromJson = '${result.name}.fromJsonString'; var fromJson = '${result.name}.fromJsonString';
var toJson = '${result.name}.toJsonString'; var toJson = '${result.name}.toJsonString';
if (isJsonStringArray) { if (isJsonStringArray) {
fromJson = '_${_toDartName('${identifier}FromJsonString')}'; fromJson = '_${_toDartName('${state.prefix}${identifier}FromJsonString')}';
if (!state.resolvedTypes.contains(fromJson)) { if (!state.resolvedTypes.contains(fromJson)) {
state.resolvedTypes.add(fromJson); state.resolvedTypes.add(fromJson);
state.output.add( state.output.add(
@ -1200,7 +1207,7 @@ TypeResult resolveObject(
), ),
); );
} }
toJson = '_${_toDartName('${identifier}ToJsonString')}'; toJson = '_${_toDartName('${state.prefix}${identifier}ToJsonString')}';
if (!state.resolvedTypes.contains(toJson)) { if (!state.resolvedTypes.contains(toJson)) {
state.resolvedTypes.add(toJson); state.resolvedTypes.add(toJson);
state.output.add( state.output.add(
@ -1253,7 +1260,7 @@ TypeResult resolveObject(
); );
} }
return TypeResultObject( return TypeResultObject(
identifier, '${state.prefix}$identifier',
fromJsonString: fromJsonString, fromJsonString: fromJsonString,
); );
} }
@ -1280,8 +1287,8 @@ TypeResult resolveType(
fromJsonString: fromJsonString, fromJsonString: fromJsonString,
); );
} else if (schema.ofs != null) { } else if (schema.ofs != null) {
if (!state.resolvedTypes.contains(identifier)) { if (!state.resolvedTypes.contains('${state.prefix}$identifier')) {
state.resolvedTypes.add(identifier); state.resolvedTypes.add('${state.prefix}$identifier');
final results = schema.ofs! final results = schema.ofs!
.map( .map(
(final s) => resolveType( (final s) => resolveType(
@ -1298,12 +1305,12 @@ TypeResult resolveType(
(final b) { (final b) {
final fields = <String, String>{}; final fields = <String, String>{};
for (final result in results) { for (final result in results) {
final dartName = _toDartName(result.name); final dartName = _toDartName(result.name.replaceFirst(state.prefix, ''));
fields[result.name] = _toFieldName(dartName, result.name); fields[result.name] = _toFieldName(dartName, result.name.replaceFirst(state.prefix, ''));
} }
b b
..name = identifier ..name = '${state.prefix}$identifier'
..fields.addAll([ ..fields.addAll([
Field( Field(
(final b) { (final b) {
@ -1398,7 +1405,7 @@ TypeResult resolveType(
if (schema.allOf != null) ...[ if (schema.allOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length == ${fields.length}, 'Need allOf for \$data');", "assert([${fields.values.join(',')}].where((final x) => x != null).length == ${fields.length}, 'Need allOf for \$data');",
], ],
'return $identifier(', 'return ${state.prefix}$identifier(',
'data,', 'data,',
for (final result in results) ...[ for (final result in results) ...[
'${fields[result.name]!}: ${fields[result.name]!},', '${fields[result.name]!}: ${fields[result.name]!},',
@ -1421,7 +1428,7 @@ TypeResult resolveType(
..type = refer('String'), ..type = refer('String'),
), ),
) )
..body = Code('$identifier.fromJson(json.decode(data))'); ..body = Code('${state.prefix}$identifier.fromJson(json.decode(data))');
}, },
), ),
]) ])
@ -1454,7 +1461,7 @@ TypeResult resolveType(
); );
} }
result = TypeResultObject(identifier); result = TypeResultObject('${state.prefix}$identifier');
} else { } else {
switch (schema.type) { switch (schema.type) {
case 'boolean': case 'boolean':
@ -1538,12 +1545,12 @@ TypeResult resolveType(
if (result != null) { if (result != null) {
if (!ignoreEnum && schema.enum_ != null) { if (!ignoreEnum && schema.enum_ != null) {
if (!state.resolvedTypes.contains(identifier)) { if (!state.resolvedTypes.contains('${state.prefix}$identifier')) {
state.resolvedTypes.add(identifier); state.resolvedTypes.add('${state.prefix}$identifier');
state.output.add( state.output.add(
Enum( Enum(
(final b) => b (final b) => b
..name = identifier ..name = '${state.prefix}$identifier'
..constructors.add( ..constructors.add(
Constructor( Constructor(
(final b) => b (final b) => b
@ -1587,7 +1594,7 @@ TypeResult resolveType(
throw Exception( throw Exception(
'Sorry enum values are a bit broken. ' 'Sorry enum values are a bit broken. '
'See https://github.com/google/json_serializable.dart/issues/616. ' 'See https://github.com/google/json_serializable.dart/issues/616. '
'Please remove the enum values on $identifier.', 'Please remove the enum values on ${state.prefix}$identifier.',
); );
} }
b.annotations.add( b.annotations.add(
@ -1605,7 +1612,7 @@ TypeResult resolveType(
(final b) => b (final b) => b
..name = 'fromValue' ..name = 'fromValue'
..static = true ..static = true
..returns = refer(identifier) ..returns = refer('${state.prefix}$identifier')
..requiredParameters.add( ..requiredParameters.add(
Parameter( Parameter(
(final b) => b (final b) => b
@ -1618,10 +1625,10 @@ TypeResult resolveType(
'switch (value) {', 'switch (value) {',
for (final value in schema.enum_!) ...[ for (final value in schema.enum_!) ...[
'case ${_valueToEscapedValue(result!.name, value)}:', 'case ${_valueToEscapedValue(result!.name, value)}:',
'return $identifier.${_toDartName(value.toString())};', 'return ${state.prefix}$identifier.${_toDartName(value.toString())};',
], ],
'default:', 'default:',
'throw Exception(\'Can not parse $identifier from "\$value"\');', 'throw Exception(\'Can not parse ${state.prefix}$identifier from "\$value"\');',
'}', '}',
].join(), ].join(),
), ),
@ -1630,7 +1637,7 @@ TypeResult resolveType(
), ),
); );
} }
result = TypeResultEnum(identifier, result); result = TypeResultEnum('${state.prefix}$identifier', result);
} }
return result; return result;

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

@ -28,7 +28,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
late GlobalOptions _globalOptions; late GlobalOptions _globalOptions;
late AccountsBloc _accountsBloc; late AccountsBloc _accountsBloc;
CoreServerCapabilities_Ocs_Data_Capabilities_Theming? _nextcloudTheme; NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? _nextcloudTheme;
final _platformBrightness = BehaviorSubject<Brightness>.seeded(WidgetsBinding.instance.window.platformBrightness); final _platformBrightness = BehaviorSubject<Brightness>.seeded(WidgetsBinding.instance.window.platformBrightness);
Rect? _lastBounds; Rect? _lastBounds;

2
packages/neon/lib/src/apps/news/blocs/article.dart

@ -20,7 +20,7 @@ class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents,
NewsArticleBloc( NewsArticleBloc(
this._client, this._client,
this._newsArticlesBloc, this._newsArticlesBloc,
final NewsArticle article, final NextcloudNewsArticle article,
) { ) {
_id = article.id; _id = article.id;
unread.add(article.unread); unread.add(article.unread);

22
packages/neon/lib/src/apps/news/blocs/articles.dart

@ -14,17 +14,17 @@ enum ListType {
abstract class NewsArticlesBlocEvents { abstract class NewsArticlesBlocEvents {
void setFilterType(final FilterType type); void setFilterType(final FilterType type);
void markArticleAsRead(final NewsArticle article); void markArticleAsRead(final NextcloudNewsArticle article);
void markArticleAsUnread(final NewsArticle article); void markArticleAsUnread(final NextcloudNewsArticle article);
void starArticle(final NewsArticle article); void starArticle(final NextcloudNewsArticle article);
void unstarArticle(final NewsArticle article); void unstarArticle(final NextcloudNewsArticle article);
} }
abstract class NewsArticlesBlocStates { abstract class NewsArticlesBlocStates {
BehaviorSubject<Result<List<NewsArticle>>> get articles; BehaviorSubject<Result<List<NextcloudNewsArticle>>> get articles;
BehaviorSubject<FilterType> get filterType; BehaviorSubject<FilterType> get filterType;
} }
@ -72,7 +72,7 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
BehaviorSubject<Result<List<NewsArticle>>> articles = BehaviorSubject<Result<List<NewsArticle>>>(); BehaviorSubject<Result<List<NextcloudNewsArticle>>> articles = BehaviorSubject<Result<List<NextcloudNewsArticle>>>();
@override @override
BehaviorSubject<FilterType> filterType = BehaviorSubject<FilterType>(); BehaviorSubject<FilterType> filterType = BehaviorSubject<FilterType>();
@ -125,7 +125,7 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
break; break;
} }
await requestManager.wrapNextcloud<List<NewsArticle>, NewsListArticles>( await requestManager.wrapNextcloud<List<NextcloudNewsArticle>, NextcloudNewsListArticles>(
client.id, client.id,
'news-articles-${type.code}-$id-$getRead', 'news-articles-${type.code}-$id-$getRead',
articles, articles,
@ -139,12 +139,12 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
void markArticleAsRead(final NewsArticle article) { void markArticleAsRead(final NextcloudNewsArticle article) {
wrapAction(() async => client.news.markArticleAsRead(itemId: article.id)); wrapAction(() async => client.news.markArticleAsRead(itemId: article.id));
} }
@override @override
void markArticleAsUnread(final NewsArticle article) { void markArticleAsUnread(final NextcloudNewsArticle article) {
wrapAction(() async => client.news.markArticleAsUnread(itemId: article.id)); wrapAction(() async => client.news.markArticleAsUnread(itemId: article.id));
} }
@ -154,12 +154,12 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
} }
@override @override
void starArticle(final NewsArticle article) { void starArticle(final NextcloudNewsArticle article) {
wrapAction(() async => client.news.starArticle(itemId: article.id)); wrapAction(() async => client.news.starArticle(itemId: article.id));
} }
@override @override
void unstarArticle(final NewsArticle article) { void unstarArticle(final NextcloudNewsArticle article) {
wrapAction(() async => client.news.unstarArticle(itemId: article.id)); wrapAction(() async => client.news.unstarArticle(itemId: article.id));
} }
} }

22
packages/neon/lib/src/apps/news/blocs/news.dart

@ -21,9 +21,9 @@ abstract class NewsBlocEvents {
} }
abstract class NewsBlocStates { abstract class NewsBlocStates {
BehaviorSubject<Result<List<NewsFolder>>> get folders; BehaviorSubject<Result<List<NextcloudNewsFolder>>> get folders;
BehaviorSubject<Result<List<NewsFeed>>> get feeds; BehaviorSubject<Result<List<NextcloudNewsFeed>>> get feeds;
BehaviorSubject<int> get unreadCounter; BehaviorSubject<int> get unreadCounter;
} }
@ -77,16 +77,16 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
BehaviorSubject<Result<List<NewsFeed>>> feeds = BehaviorSubject<Result<List<NewsFeed>>>(); BehaviorSubject<Result<List<NextcloudNewsFeed>>> feeds = BehaviorSubject<Result<List<NextcloudNewsFeed>>>();
@override @override
BehaviorSubject<Result<List<NewsFolder>>> folders = BehaviorSubject<Result<List<NewsFolder>>>(); BehaviorSubject<Result<List<NextcloudNewsFolder>>> folders = BehaviorSubject<Result<List<NextcloudNewsFolder>>>();
@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<NextcloudNewsArticle>>> articles = mainArticlesBloc.articles;
@override @override
late BehaviorSubject<FilterType> filterType = mainArticlesBloc.filterType; late BehaviorSubject<FilterType> filterType = mainArticlesBloc.filterType;
@ -94,14 +94,14 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
@override @override
Future refresh() async { Future refresh() async {
await Future.wait([ await Future.wait([
requestManager.wrapNextcloud<List<NewsFolder>, NewsListFolders>( requestManager.wrapNextcloud<List<NextcloudNewsFolder>, NextcloudNewsListFolders>(
client.id, client.id,
'news-folders', 'news-folders',
folders, folders,
() async => client.news.listFolders(), () async => client.news.listFolders(),
(final response) => response.folders, (final response) => response.folders,
), ),
requestManager.wrapNextcloud<List<NewsFeed>, NewsListFeeds>( requestManager.wrapNextcloud<List<NextcloudNewsFeed>, NextcloudNewsListFeeds>(
client.id, client.id,
'news-feeds', 'news-feeds',
feeds, feeds,
@ -164,12 +164,12 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
void markArticleAsRead(final NewsArticle article) { void markArticleAsRead(final NextcloudNewsArticle article) {
mainArticlesBloc.markArticleAsRead(article); mainArticlesBloc.markArticleAsRead(article);
} }
@override @override
void markArticleAsUnread(final NewsArticle article) { void markArticleAsUnread(final NextcloudNewsArticle article) {
mainArticlesBloc.markArticleAsUnread(article); mainArticlesBloc.markArticleAsUnread(article);
} }
@ -179,12 +179,12 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
} }
@override @override
void starArticle(final NewsArticle article) { void starArticle(final NextcloudNewsArticle article) {
mainArticlesBloc.starArticle(article); mainArticlesBloc.starArticle(article);
} }
@override @override
void unstarArticle(final NewsArticle article) { void unstarArticle(final NextcloudNewsArticle article) {
mainArticlesBloc.unstarArticle(article); mainArticlesBloc.unstarArticle(article);
} }

4
packages/neon/lib/src/apps/news/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; NextcloudNewsFolder? folder;
void submit() { void submit() {
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {
@ -43,7 +43,7 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NewsFolder>>( Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NextcloudNewsFolder>>(
stream: widget.bloc.folders, stream: widget.bloc.folders,
builder: (final context, final folders) => CustomDialog( builder: (final context, final folders) => CustomDialog(
title: Text(AppLocalizations.of(context).newsAddFeed), title: Text(AppLocalizations.of(context).newsAddFeed),

2
packages/neon/lib/src/apps/news/dialogs/feed_show_url.dart

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

2
packages/neon/lib/src/apps/news/dialogs/feed_update_error.dart

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

6
packages/neon/lib/src/apps/news/dialogs/move_feed.dart

@ -7,8 +7,8 @@ class NewsMoveFeedDialog extends StatefulWidget {
super.key, super.key,
}); });
final List<NewsFolder> folders; final List<NextcloudNewsFolder> folders;
final NewsFeed feed; final NextcloudNewsFeed 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; NextcloudNewsFolder? folder;
void submit() { void submit() {
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {

2
packages/neon/lib/src/apps/news/pages/feed.dart

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

2
packages/neon/lib/src/apps/news/pages/folder.dart

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

2
packages/neon/lib/src/apps/news/sort/articles.dart

@ -1,6 +1,6 @@
part of '../app.dart'; part of '../app.dart';
final articlesSortBox = SortBox<ArticlesSortProperty, NewsArticle>( final articlesSortBox = SortBox<ArticlesSortProperty, NextcloudNewsArticle>(
{ {
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/lib/src/apps/news/sort/feeds.dart

@ -1,6 +1,6 @@
part of '../app.dart'; part of '../app.dart';
final feedsSortBox = SortBox<FeedsSortProperty, NewsFeed>( final feedsSortBox = SortBox<FeedsSortProperty, NextcloudNewsFeed>(
{ {
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,

6
packages/neon/lib/src/apps/news/sort/folders.dart

@ -17,11 +17,11 @@ class FolderFeedsWrapper {
this.feeds, this.feeds,
); );
final NewsFolder folder; final NextcloudNewsFolder folder;
final List<NewsFeed> feeds; final List<NextcloudNewsFeed> feeds;
} }
int feedsUnreadCountSum(final List<NewsFeed> feeds) => [ int feedsUnreadCountSum(final List<NextcloudNewsFeed> feeds) => [
0, // Fixes error when no feeds are in the folder 0, // Fixes error when no feeds are in the folder
...feeds.map((final f) => f.unreadCount!), ...feeds.map((final f) => f.unreadCount!),
].reduce( ].reduce(

12
packages/neon/lib/src/apps/news/widgets/articles_view.dart

@ -25,18 +25,18 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NewsFeed>>( Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NextcloudNewsFeed>>(
stream: widget.newsBloc.feeds, stream: widget.newsBloc.feeds,
builder: (final context, final feeds) => ResultBuilder<NewsArticlesBloc, List<NewsArticle>>( builder: (final context, final feeds) => ResultBuilder<NewsArticlesBloc, List<NextcloudNewsArticle>>(
stream: widget.bloc.articles, stream: widget.bloc.articles,
builder: (final context, final articles) => Scaffold( builder: (final context, final articles) => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
body: SortBoxBuilder<ArticlesSortProperty, NewsArticle>( body: SortBoxBuilder<ArticlesSortProperty, NextcloudNewsArticle>(
sortBox: articlesSortBox, sortBox: articlesSortBox,
sortPropertyOption: widget.newsBloc.options.articlesSortPropertyOption, sortPropertyOption: widget.newsBloc.options.articlesSortPropertyOption,
sortBoxOrderOption: widget.newsBloc.options.articlesSortBoxOrderOption, sortBoxOrderOption: widget.newsBloc.options.articlesSortBoxOrderOption,
input: articles.data, input: articles.data,
builder: (final context, final sorted) => CustomListView<NewsArticle>( builder: (final context, final sorted) => CustomListView<NextcloudNewsArticle>(
scrollKey: 'news-articles', scrollKey: 'news-articles',
items: feeds.data == null ? null : sorted, items: feeds.data == null ? null : sorted,
isLoading: articles.loading || feeds.loading, isLoading: articles.loading || feeds.loading,
@ -103,8 +103,8 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
Widget _buildArticle( Widget _buildArticle(
final BuildContext context, final BuildContext context,
final NewsArticle article, final NextcloudNewsArticle article,
final NewsFeed feed, final NextcloudNewsFeed feed,
) => ) =>
ListTile( ListTile(
title: Row( title: Row(

2
packages/neon/lib/src/apps/news/widgets/feed_icon.dart

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

12
packages/neon/lib/src/apps/news/widgets/feeds_view.dart

@ -11,9 +11,9 @@ class NewsFeedsView extends StatelessWidget {
final int? folderID; final int? folderID;
@override @override
Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NewsFolder>>( Widget build(final BuildContext context) => ResultBuilder<NewsBloc, List<NextcloudNewsFolder>>(
stream: bloc.folders, stream: bloc.folders,
builder: (final context, final folders) => ResultBuilder<NewsBloc, List<NewsFeed>>( builder: (final context, final folders) => ResultBuilder<NewsBloc, List<NextcloudNewsFeed>>(
stream: bloc.feeds, stream: bloc.feeds,
builder: (final context, final feeds) => Scaffold( builder: (final context, final feeds) => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
@ -32,14 +32,14 @@ class NewsFeedsView extends StatelessWidget {
}, },
child: const Icon(Icons.add), child: const Icon(Icons.add),
), ),
body: SortBoxBuilder<FeedsSortProperty, NewsFeed>( body: SortBoxBuilder<FeedsSortProperty, NextcloudNewsFeed>(
sortBox: feedsSortBox, sortBox: feedsSortBox,
sortPropertyOption: bloc.options.feedsSortPropertyOption, sortPropertyOption: bloc.options.feedsSortPropertyOption,
sortBoxOrderOption: bloc.options.feedsSortBoxOrderOption, sortBoxOrderOption: bloc.options.feedsSortBoxOrderOption,
input: folders.data == null input: folders.data == null
? null ? null
: feeds.data?.where((final f) => folderID == null || f.folderId == folderID).toList(), : feeds.data?.where((final f) => folderID == null || f.folderId == folderID).toList(),
builder: (final context, final sorted) => CustomListView<NewsFeed>( builder: (final context, final sorted) => CustomListView<NextcloudNewsFeed>(
scrollKey: 'news-feeds', scrollKey: 'news-feeds',
withFloatingActionButton: true, withFloatingActionButton: true,
items: sorted, items: sorted,
@ -59,8 +59,8 @@ class NewsFeedsView extends StatelessWidget {
Widget _buildFeed( Widget _buildFeed(
final BuildContext context, final BuildContext context,
final NewsFeed feed, final NextcloudNewsFeed feed,
final List<NewsFolder> folders, final List<NextcloudNewsFolder> folders,
) => ) =>
ListTile( ListTile(
title: Text( title: Text(

10
packages/neon/lib/src/apps/news/widgets/folder_select.dart

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

2
packages/neon/lib/src/apps/news/widgets/folder_view.dart

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

4
packages/neon/lib/src/apps/news/widgets/folders_view.dart

@ -23,9 +23,9 @@ class NewsFoldersView extends StatelessWidget {
}, },
child: const Icon(Icons.add), child: const Icon(Icons.add),
), ),
body: ResultBuilder<NewsBloc, List<NewsFolder>>( body: ResultBuilder<NewsBloc, List<NextcloudNewsFolder>>(
stream: bloc.folders, stream: bloc.folders,
builder: (final context, final folders) => ResultBuilder<NewsBloc, List<NewsFeed>>( builder: (final context, final folders) => ResultBuilder<NewsBloc, List<NextcloudNewsFeed>>(
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,

6
packages/neon/lib/src/apps/notes/blocs/note.dart

@ -17,7 +17,7 @@ class NotesNoteBloc extends InteractiveBloc implements NotesNoteBlocEvents, Note
this.options, this.options,
this._client, this._client,
this._notesBloc, this._notesBloc,
final NotesNote note, final NextcloudNotesNote note,
) { ) {
_emitNote(note); _emitNote(note);
id = note.id; id = note.id;
@ -25,13 +25,13 @@ class NotesNoteBloc extends InteractiveBloc implements NotesNoteBlocEvents, Note
initialTitle = note.title; initialTitle = note.title;
} }
void _emitNote(final NotesNote note) { void _emitNote(final NextcloudNotesNote 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<NotesNote> Function(String etag) call) async { void _wrapAction(final Future<NextcloudNotesNote> Function(String etag) call) async {
await _updateQueue.add(() async { await _updateQueue.add(() async {
try { try {
final data = await call(_etag); final data = await call(_etag);

6
packages/neon/lib/src/apps/notes/blocs/notes.dart

@ -19,7 +19,7 @@ abstract class NotesBlocEvents {
} }
abstract class NotesBlocStates { abstract class NotesBlocStates {
BehaviorSubject<Result<List<NotesNote>>> get notes; BehaviorSubject<Result<List<NextcloudNotesNote>>> get notes;
} }
class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocStates { class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocStates {
@ -42,11 +42,11 @@ class NotesBloc extends InteractiveBloc implements NotesBlocEvents, NotesBlocSta
} }
@override @override
BehaviorSubject<Result<List<NotesNote>>> notes = BehaviorSubject<Result<List<NotesNote>>>(); BehaviorSubject<Result<List<NextcloudNotesNote>>> notes = BehaviorSubject<Result<List<NextcloudNotesNote>>>();
@override @override
Future refresh() async { Future refresh() async {
await requestManager.wrapNextcloud<List<NotesNote>, List<NotesNote>>( await requestManager.wrapNextcloud<List<NextcloudNotesNote>, List<NextcloudNotesNote>>(
client.id, client.id,
'notes-notes', 'notes-notes',
notes, notes,

2
packages/neon/lib/src/apps/notes/dialogs/create_note.dart

@ -26,7 +26,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NotesNote>>( Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NextcloudNotesNote>>(
stream: widget.bloc.notes, stream: widget.bloc.notes,
builder: (final context, final notes) => CustomDialog( builder: (final context, final notes) => CustomDialog(
title: Text(AppLocalizations.of(context).notesCreateNote), title: Text(AppLocalizations.of(context).notesCreateNote),

2
packages/neon/lib/src/apps/notes/dialogs/select_category.dart

@ -26,7 +26,7 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NotesNote>>( Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NextcloudNotesNote>>(
stream: widget.bloc.notes, stream: widget.bloc.notes,
builder: (final context, final notes) => CustomDialog( builder: (final context, final notes) => CustomDialog(
title: Text(AppLocalizations.of(context).notesChangeCategory), title: Text(AppLocalizations.of(context).notesChangeCategory),

2
packages/neon/lib/src/apps/notes/sort/notes.dart

@ -1,6 +1,6 @@
part of '../app.dart'; part of '../app.dart';
final notesSortBox = SortBox<NotesSortProperty, NotesNote>( final notesSortBox = SortBox<NotesSortProperty, NextcloudNotesNote>(
{ {
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,

2
packages/neon/lib/src/apps/notes/utils/exception_handler.dart

@ -1,7 +1,7 @@
part of '../app.dart'; part of '../app.dart';
void handleNotesException(final BuildContext context, final Object error) { void handleNotesException(final BuildContext context, final Object error) {
if (error is ApiException && error.statusCode == 412) { if (error is NextcloudApiException && error.statusCode == 412) {
ExceptionWidget.showSnackbar(context, AppLocalizations.of(context).notesNoteChangedOnServer); ExceptionWidget.showSnackbar(context, AppLocalizations.of(context).notesNoteChangedOnServer);
} else { } else {
ExceptionWidget.showSnackbar(context, error); ExceptionWidget.showSnackbar(context, error);

2
packages/neon/lib/src/apps/notes/widgets/categories_view.dart

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

10
packages/neon/lib/src/apps/notes/widgets/notes_view.dart

@ -11,7 +11,7 @@ class NotesView extends StatelessWidget {
final String? category; final String? category;
@override @override
Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NotesNote>>( Widget build(final BuildContext context) => ResultBuilder<NotesBloc, List<NextcloudNotesNote>>(
stream: bloc.notes, stream: bloc.notes,
builder: (final context, final notes) => Scaffold( builder: (final context, final notes) => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
@ -33,21 +33,21 @@ class NotesView extends StatelessWidget {
}, },
child: const Icon(Icons.add), child: const Icon(Icons.add),
), ),
body: SortBoxBuilder<NotesSortProperty, NotesNote>( body: SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
sortBox: notesSortBox, sortBox: notesSortBox,
sortPropertyOption: bloc.options.notesSortPropertyOption, sortPropertyOption: bloc.options.notesSortPropertyOption,
sortBoxOrderOption: bloc.options.notesSortBoxOrderOption, sortBoxOrderOption: bloc.options.notesSortBoxOrderOption,
input: category != null input: category != null
? notes.data?.where((final note) => note.favorite && note.category == category).toList() ? notes.data?.where((final note) => note.favorite && note.category == category).toList()
: notes.data?.where((final note) => note.favorite).toList(), : notes.data?.where((final note) => note.favorite).toList(),
builder: (final context, final sortedFavorites) => SortBoxBuilder<NotesSortProperty, NotesNote>( builder: (final context, final sortedFavorites) => SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
sortBox: notesSortBox, sortBox: notesSortBox,
sortPropertyOption: bloc.options.notesSortPropertyOption, sortPropertyOption: bloc.options.notesSortPropertyOption,
sortBoxOrderOption: bloc.options.notesSortBoxOrderOption, sortBoxOrderOption: bloc.options.notesSortBoxOrderOption,
input: category != null input: category != null
? notes.data?.where((final note) => !note.favorite && note.category == category).toList() ? notes.data?.where((final note) => !note.favorite && note.category == category).toList()
: notes.data?.where((final note) => !note.favorite).toList(), : notes.data?.where((final note) => !note.favorite).toList(),
builder: (final context, final sortedNonFavorites) => CustomListView<NotesNote>( builder: (final context, final sortedNonFavorites) => CustomListView<NextcloudNotesNote>(
scrollKey: 'notes-notes', scrollKey: 'notes-notes',
withFloatingActionButton: true, withFloatingActionButton: true,
items: [ items: [
@ -70,7 +70,7 @@ class NotesView extends StatelessWidget {
Widget _buildNote( Widget _buildNote(
final BuildContext context, final BuildContext context,
final NotesNote note, final NextcloudNotesNote note,
) => ) =>
ListTile( ListTile(
title: Text(note.title), title: Text(note.title),

9
packages/neon/lib/src/apps/notifications/blocs/notifications.dart

@ -7,7 +7,7 @@ abstract class NotificationsBlocEvents {
} }
abstract class NotificationsBlocStates { abstract class NotificationsBlocStates {
BehaviorSubject<Result<List<NotificationsNotification>>> get notifications; BehaviorSubject<Result<List<NextcloudNotificationsNotification>>> get notifications;
BehaviorSubject<int> get unreadCounter; BehaviorSubject<int> get unreadCounter;
} }
@ -39,15 +39,16 @@ class NotificationsBloc extends InteractiveBloc implements NotificationsBlocEven
} }
@override @override
BehaviorSubject<Result<List<NotificationsNotification>>> notifications = BehaviorSubject<Result<List<NextcloudNotificationsNotification>>> notifications =
BehaviorSubject<Result<List<NotificationsNotification>>>(); BehaviorSubject<Result<List<NextcloudNotificationsNotification>>>();
@override @override
BehaviorSubject<int> unreadCounter = BehaviorSubject<int>(); BehaviorSubject<int> unreadCounter = BehaviorSubject<int>();
@override @override
Future refresh() async { Future refresh() async {
await _requestManager.wrapNextcloud<List<NotificationsNotification>, NotificationsListNotifications>( await _requestManager
.wrapNextcloud<List<NextcloudNotificationsNotification>, NextcloudNotificationsListNotifications>(
_client.id, _client.id,
'notifications-notifications', 'notifications-notifications',
notifications, notifications,

7
packages/neon/lib/src/apps/notifications/pages/main.dart

@ -23,7 +23,8 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
} }
@override @override
Widget build(final BuildContext context) => ResultBuilder<NotificationsBloc, List<NotificationsNotification>>( Widget build(final BuildContext context) =>
ResultBuilder<NotificationsBloc, List<NextcloudNotificationsNotification>>(
stream: widget.bloc.notifications, stream: widget.bloc.notifications,
builder: (final context, final notifications) => Scaffold( builder: (final context, final notifications) => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
@ -33,7 +34,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
}, },
child: const Icon(MdiIcons.checkAll), child: const Icon(MdiIcons.checkAll),
), ),
body: CustomListView<NotificationsNotification>( body: CustomListView<NextcloudNotificationsNotification>(
scrollKey: 'notifications-notifications', scrollKey: 'notifications-notifications',
withFloatingActionButton: true, withFloatingActionButton: true,
items: notifications.data, items: notifications.data,
@ -47,7 +48,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
Widget _buildNotification( Widget _buildNotification(
final BuildContext context, final BuildContext context,
final NotificationsNotification notification, final NextcloudNotificationsNotification notification,
) { ) {
final matchingAppImplementations = Provider.of<List<AppImplementation>>(context, listen: false) final matchingAppImplementations = Provider.of<List<AppImplementation>>(context, listen: false)
.where((final a) => a.id == notification.app) .where((final a) => a.id == notification.app)

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

@ -1,6 +1,6 @@
part of '../neon.dart'; part of '../neon.dart';
typedef NextcloudApp = CoreNavigationApps_Ocs_Data; typedef NextcloudApp = NextcloudCoreNavigationApps_Ocs_Data;
abstract class AppsBlocEvents { abstract class AppsBlocEvents {
void setActiveApp(final String? appID); void setActiveApp(final String? appID);
@ -109,7 +109,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
@override @override
Future refresh() async { Future refresh() async {
await _requestManager.wrapNextcloud<List<NextcloudApp>, CoreNavigationApps>( await _requestManager.wrapNextcloud<List<NextcloudApp>, NextcloudCoreNavigationApps>(
_account.client.id, _account.client.id,
'apps-apps', 'apps-apps',
apps, apps,

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

@ -1,7 +1,7 @@
part of '../neon.dart'; part of '../neon.dart';
typedef Capabilities = CoreServerCapabilities_Ocs_Data; typedef Capabilities = NextcloudCoreServerCapabilities_Ocs_Data;
typedef NextcloudTheme = CoreServerCapabilities_Ocs_Data_Capabilities_Theming; typedef NextcloudTheme = NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming;
abstract class CapabilitiesBlocEvents {} abstract class CapabilitiesBlocEvents {}
@ -31,7 +31,7 @@ class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents
@override @override
Future refresh() async { Future refresh() async {
await _requestManager.wrapNextcloud<CoreServerCapabilities_Ocs_Data, CoreServerCapabilities>( await _requestManager.wrapNextcloud<NextcloudCoreServerCapabilities_Ocs_Data, NextcloudCoreServerCapabilities>(
_client.id, _client.id,
'capabilities', 'capabilities',
capabilities, capabilities,

10
packages/neon/lib/src/blocs/login.dart

@ -9,9 +9,9 @@ abstract class LoginBlocStates {
BehaviorSubject<ServerConnectionState?> get serverConnectionState; BehaviorSubject<ServerConnectionState?> get serverConnectionState;
BehaviorSubject<CoreLoginFlowInit?> get loginFlowInit; BehaviorSubject<NextcloudCoreLoginFlowInit?> get loginFlowInit;
BehaviorSubject<CoreLoginFlowResult?> get loginFlowResult; BehaviorSubject<NextcloudCoreLoginFlowResult?> get loginFlowResult;
} }
class LoginBloc extends InteractiveBloc implements LoginBlocEvents, LoginBlocStates { class LoginBloc extends InteractiveBloc implements LoginBlocEvents, LoginBlocStates {
@ -31,10 +31,12 @@ class LoginBloc extends InteractiveBloc implements LoginBlocEvents, LoginBlocSta
} }
@override @override
BehaviorSubject<CoreLoginFlowInit?> loginFlowInit = BehaviorSubject<CoreLoginFlowInit?>.seeded(null); BehaviorSubject<NextcloudCoreLoginFlowInit?> loginFlowInit =
BehaviorSubject<NextcloudCoreLoginFlowInit?>.seeded(null);
@override @override
BehaviorSubject<CoreLoginFlowResult?> loginFlowResult = BehaviorSubject<CoreLoginFlowResult?>.seeded(null); BehaviorSubject<NextcloudCoreLoginFlowResult?> loginFlowResult =
BehaviorSubject<NextcloudCoreLoginFlowResult?>.seeded(null);
@override @override
BehaviorSubject<ServerConnectionState?> serverConnectionState = BehaviorSubject<ServerConnectionState?>.seeded(null); BehaviorSubject<ServerConnectionState?> serverConnectionState = BehaviorSubject<ServerConnectionState?>.seeded(null);

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

@ -143,5 +143,5 @@ class NextcloudPushNotification {
final String instance; final String instance;
final String priority; final String priority;
final String type; final String type;
final NotificationsPushNotificationDecryptedSubject subject; final NextcloudNotificationsPushNotificationDecryptedSubject subject;
} }

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

@ -3,7 +3,7 @@ part of '../neon.dart';
abstract class UserDetailsBlocEvents {} abstract class UserDetailsBlocEvents {}
abstract class UserDetailsBlocStates { abstract class UserDetailsBlocStates {
BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails; BehaviorSubject<Result<NextcloudProvisioningApiUserDetails>> get userDetails;
} }
class UserDetailsBloc extends InteractiveBloc implements UserDetailsBlocEvents, UserDetailsBlocStates { class UserDetailsBloc extends InteractiveBloc implements UserDetailsBlocEvents, UserDetailsBlocStates {
@ -24,12 +24,12 @@ class UserDetailsBloc extends InteractiveBloc implements UserDetailsBlocEvents,
} }
@override @override
BehaviorSubject<Result<ProvisioningApiUserDetails>> userDetails = BehaviorSubject<Result<NextcloudProvisioningApiUserDetails>> userDetails =
BehaviorSubject<Result<ProvisioningApiUserDetails>>(); BehaviorSubject<Result<NextcloudProvisioningApiUserDetails>>();
@override @override
Future refresh() async { Future refresh() async {
await _requestManager.wrapNextcloud<ProvisioningApiUserDetails, ProvisioningApiUser>( await _requestManager.wrapNextcloud<NextcloudProvisioningApiUserDetails, NextcloudProvisioningApiUser>(
_client.id, _client.id,
'user-details', 'user-details',
userDetails, userDetails,

8
packages/neon/lib/src/blocs/user_status.dart

@ -3,7 +3,7 @@ part of '../neon.dart';
abstract class UserStatusBlocEvents {} abstract class UserStatusBlocEvents {}
abstract class UserStatusBlocStates { abstract class UserStatusBlocStates {
BehaviorSubject<Result<UserStatus?>> get userStatus; BehaviorSubject<Result<NextcloudUserStatus?>> get userStatus;
} }
class UserStatusBloc extends InteractiveBloc implements UserStatusBlocEvents, UserStatusBlocStates { class UserStatusBloc extends InteractiveBloc implements UserStatusBlocEvents, UserStatusBlocStates {
@ -30,7 +30,7 @@ class UserStatusBloc extends InteractiveBloc implements UserStatusBlocEvents, Us
} }
@override @override
BehaviorSubject<Result<UserStatus?>> userStatus = BehaviorSubject<Result<UserStatus?>>(); BehaviorSubject<Result<NextcloudUserStatus?>> userStatus = BehaviorSubject<Result<NextcloudUserStatus?>>();
@override @override
Future refresh() async { Future refresh() async {
@ -38,11 +38,11 @@ class UserStatusBloc extends InteractiveBloc implements UserStatusBlocEvents, Us
_platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible())); _platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible()));
try { try {
final status = await _account.client.userStatus.heartbeat( final status = await _account.client.userStatus.heartbeat(
status: isAway ? UserStatusType.away : UserStatusType.online, status: isAway ? NextcloudUserStatusType.away : NextcloudUserStatusType.online,
); );
userStatus.add(Result.success(status)); userStatus.add(Result.success(status));
} catch (e) { } catch (e) {
if (e is ApiException && e.statusCode == 204) { if (e is NextcloudApiException && e.statusCode == 204) {
return; return;
} }
userStatus.add(Result.error(e)); userStatus.add(Result.error(e));

2
packages/neon/lib/src/models/push_notification_with_account.dart

@ -14,7 +14,7 @@ class PushNotificationWithAccountID {
_$PushNotificationWithAccountIDFromJson(json); _$PushNotificationWithAccountIDFromJson(json);
Map<String, dynamic> toJson() => _$PushNotificationWithAccountIDToJson(this); Map<String, dynamic> toJson() => _$PushNotificationWithAccountIDToJson(this);
final NotificationsPushNotification notification; final NextcloudNotificationsPushNotification notification;
final String accountID; final String accountID;
} }

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

@ -8,7 +8,7 @@ part of 'push_notification_with_account.dart';
PushNotificationWithAccountID _$PushNotificationWithAccountIDFromJson(Map<String, dynamic> json) => PushNotificationWithAccountID _$PushNotificationWithAccountIDFromJson(Map<String, dynamic> json) =>
PushNotificationWithAccountID( PushNotificationWithAccountID(
notification: NotificationsPushNotification.fromJson(json['notification'] as Map<String, dynamic>), notification: NextcloudNotificationsPushNotification.fromJson(json['notification'] as Map<String, dynamic>),
accountID: json['accountID'] as String, accountID: json['accountID'] as String,
); );

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

@ -45,7 +45,7 @@ class AccountSettingsPage extends StatelessWidget {
), ),
], ],
), ),
body: ResultBuilder<UserDetailsBloc, ProvisioningApiUserDetails>( body: ResultBuilder<UserDetailsBloc, NextcloudProvisioningApiUserDetails>(
stream: _userDetailsBloc.userDetails, stream: _userDetailsBloc.userDetails,
builder: (final context, final userDetails) => SettingsList( builder: (final context, final userDetails) => SettingsList(
categories: [ categories: [

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

@ -53,7 +53,7 @@ class PushUtils {
final keypair = await loadRSAKeypair(AppStorage('notifications', sharedPreferences)); final keypair = await loadRSAKeypair(AppStorage('notifications', sharedPreferences));
final data = json.decode(utf8.decode(message)) as Map<String, dynamic>; final data = json.decode(utf8.decode(message)) as Map<String, dynamic>;
final notification = NotificationsPushNotification( final notification = NextcloudNotificationsPushNotification(
accountID: instance, accountID: instance,
priority: data['priority']! as String, priority: data['priority']! as String,
type: data['type']! as String, type: data['type']! as String,
@ -127,7 +127,7 @@ class PushUtils {
static int _getNotificationID( static int _getNotificationID(
final String instance, final String instance,
final NotificationsPushNotification notification, final NextcloudNotificationsPushNotification notification,
) => ) =>
sha256.convert(utf8.encode('$instance${notification.subject.nid}')).bytes.reduce((final a, final b) => a + b); sha256.convert(utf8.encode('$instance${notification.subject.nid}')).bytes.reduce((final a, final b) => a + b);
} }

2
packages/neon/lib/src/utils/theme.dart

@ -3,7 +3,7 @@ part of '../neon.dart';
const themePrimaryColor = Color(0xFFF37736); const themePrimaryColor = Color(0xFFF37736);
ThemeData getThemeFromNextcloudTheme( ThemeData getThemeFromNextcloudTheme(
final CoreServerCapabilities_Ocs_Data_Capabilities_Theming? nextcloudTheme, final NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? nextcloudTheme,
final ThemeMode themeMode, final ThemeMode themeMode,
final Brightness platformBrightness, { final Brightness platformBrightness, {
required final bool oledAsDark, required final bool oledAsDark,

13
packages/neon/lib/src/widgets/account_avatar.dart

@ -39,7 +39,7 @@ class AccountAvatar extends StatelessWidget {
), ),
), ),
), ),
ResultBuilder<UserStatusBloc, UserStatus?>( ResultBuilder<UserStatusBloc, NextcloudUserStatus?>(
stream: Provider.of<AccountsBloc>(context, listen: false).getUserStatusBloc(account).userStatus, stream: Provider.of<AccountsBloc>(context, listen: false).getUserStatusBloc(account).userStatus,
builder: (final context, final userStatus) => SizedBox( builder: (final context, final userStatus) => SizedBox(
height: kAvatarSize, height: kAvatarSize,
@ -61,7 +61,8 @@ class AccountAvatar extends StatelessWidget {
color: Theme.of(context).colorScheme.onPrimary, color: Theme.of(context).colorScheme.onPrimary,
) )
: userStatus.error != null && : userStatus.error != null &&
(userStatus.error is! ApiException || (userStatus.error! as ApiException).statusCode != 404) (userStatus.error is! NextcloudApiException ||
(userStatus.error! as NextcloudApiException).statusCode != 404)
? const Icon( ? const Icon(
Icons.error_outline, Icons.error_outline,
size: kAvatarSize / 3, size: kAvatarSize / 3,
@ -76,13 +77,13 @@ class AccountAvatar extends StatelessWidget {
); );
} }
Color _userStatusToColor(final UserStatus userStatus) { Color _userStatusToColor(final NextcloudUserStatus userStatus) {
switch (userStatus.status) { switch (userStatus.status) {
case UserStatusType.online: case NextcloudUserStatusType.online:
return const Color(0xFF49B382); return const Color(0xFF49B382);
case UserStatusType.away: case NextcloudUserStatusType.away:
return const Color(0xFFF4A331); return const Color(0xFFF4A331);
case UserStatusType.dnd: case NextcloudUserStatusType.dnd:
return const Color(0xFFED484C); return const Color(0xFFED484C);
default: default:
return Colors.transparent; return Colors.transparent;

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

@ -38,7 +38,7 @@ class AccountTile extends StatelessWidget {
account: account, account: account,
), ),
), ),
title: ResultBuilder<UserDetailsBloc, ProvisioningApiUserDetails>( title: ResultBuilder<UserDetailsBloc, NextcloudProvisioningApiUserDetails>(
stream: userDetailsBloc.userDetails, stream: userDetailsBloc.userDetails,
builder: (final context, final userDetails) => Row( builder: (final context, final userDetails) => Row(
children: [ children: [

2
packages/neon/lib/src/widgets/exception.dart

@ -108,7 +108,7 @@ class ExceptionWidget extends StatelessWidget {
); );
} }
if (exception is ApiException) { if (exception is NextcloudApiException) {
if (exception.statusCode == 401) { if (exception.statusCode == 401) {
return _ExceptionDetails( return _ExceptionDetails(
text: AppLocalizations.of(context).errorCredentialsForAccountNoLongerMatch, text: AppLocalizations.of(context).errorCredentialsForAccountNoLongerMatch,

3
packages/nextcloud/lib/nextcloud.dart

@ -7,12 +7,13 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/src/nextcloud.openapi.dart' as openapi;
import 'package:version/version.dart'; import 'package:version/version.dart';
import 'package:xml/xml.dart' as xml; import 'package:xml/xml.dart' as xml;
export 'package:crypton/crypton.dart' show RSAKeypair, RSAPublicKey, RSAPrivateKey; export 'package:crypton/crypton.dart' show RSAKeypair, RSAPublicKey, RSAPrivateKey;
export 'src/nextcloud.openapi.dart'; export 'src/nextcloud.openapi.dart' hide NextcloudClient;
part 'src/app_type.dart'; part 'src/app_type.dart';
part 'src/client.dart'; part 'src/client.dart';

4
packages/nextcloud/lib/src/client.dart

@ -1,7 +1,7 @@
part of '../nextcloud.dart'; part of '../nextcloud.dart';
// ignore: public_member_api_docs // ignore: public_member_api_docs
class NextcloudClient extends Client { class NextcloudClient extends openapi.NextcloudClient {
// ignore: public_member_api_docs // ignore: public_member_api_docs
NextcloudClient( NextcloudClient(
super.baseURL, { super.baseURL, {
@ -21,7 +21,7 @@ class NextcloudClient extends Client {
.cast<String, String>(), .cast<String, String>(),
userAgent: userAgentOverride ?? appType.userAgent, userAgent: userAgentOverride ?? appType.userAgent,
authentication: loginName != null && password != null authentication: loginName != null && password != null
? HttpBasicAuthentication( ? openapi.NextcloudHttpBasicAuthentication(
username: loginName, username: loginName,
password: password, password: password,
) )

12
packages/nextcloud/lib/src/helpers.dart

@ -2,17 +2,17 @@
part of '../nextcloud.dart'; part of '../nextcloud.dart';
extension UserDetailsDisplayName on ProvisioningApiUserDetails { extension UserDetailsDisplayName on openapi.NextcloudProvisioningApiUserDetails {
/// This is used to work around an API change that wasn't made for every endpoint /// This is used to work around an API change that wasn't made for every endpoint
/// See https://github.com/nextcloud/server/commit/5086335643b6181284ee50f57b95525002842992 /// See https://github.com/nextcloud/server/commit/5086335643b6181284ee50f57b95525002842992
String? getDisplayName() => displayname ?? displayName; String? getDisplayName() => displayname ?? displayName;
} }
extension NextcloudNotificationsPushProxy on NotificationsClient { extension NextcloudNotificationsPushProxy on NextcloudNotificationsClient {
/// Registers a device at the push proxy server /// Registers a device at the push proxy server
Future registerDeviceAtPushProxy( Future registerDeviceAtPushProxy(
final String pushToken, final String pushToken,
final NotificationsPushServerSubscription subscription, final NextcloudNotificationsPushServerSubscription subscription,
final String proxyServer, final String proxyServer,
) async { ) async {
final request = await HttpClient().postUrl(Uri.parse('${proxyServer}devices')) final request = await HttpClient().postUrl(Uri.parse('${proxyServer}devices'))
@ -38,7 +38,7 @@ extension NextcloudNotificationsPushProxy on NotificationsClient {
if (response.statusCode != 200) { if (response.statusCode != 200) {
// coverage:ignore-start // coverage:ignore-start
throw ApiException( throw NextcloudApiException(
response.statusCode, response.statusCode,
{}, // TODO {}, // TODO
await response.bodyBytes, await response.bodyBytes,
@ -52,11 +52,11 @@ extension NextcloudNotificationsPushProxy on NotificationsClient {
} }
/// Decrypts the subject of a push notification /// Decrypts the subject of a push notification
NotificationsPushNotificationDecryptedSubject decryptPushNotificationSubject( NextcloudNotificationsPushNotificationDecryptedSubject decryptPushNotificationSubject(
final RSAPrivateKey privateKey, final RSAPrivateKey privateKey,
final String subject, final String subject,
) => ) =>
NotificationsPushNotificationDecryptedSubject.fromJson( NextcloudNotificationsPushNotificationDecryptedSubject.fromJson(
json.decode(privateKey.decrypt(subject)) as Map<String, dynamic>, json.decode(privateKey.decrypt(subject)) as Map<String, dynamic>,
); );

3603
packages/nextcloud/lib/src/nextcloud.openapi.dart

File diff suppressed because it is too large Load Diff

1225
packages/nextcloud/lib/src/nextcloud.openapi.g.dart

File diff suppressed because it is too large Load Diff

10
packages/nextcloud/lib/src/version_supported.dart

@ -1,14 +1,14 @@
part of '../nextcloud.dart'; part of '../nextcloud.dart';
// ignore: public_member_api_docs // ignore: public_member_api_docs
extension CoreVersionSupported on CoreClient { extension CoreVersionSupported on NextcloudCoreClient {
/// Checks if the app on the server is supported by the client /// Checks if the app on the server is supported by the client
Future<bool> isSupported([final CoreServerCapabilities_Ocs_Data? capabilities]) async => Future<bool> isSupported([final NextcloudCoreServerCapabilities_Ocs_Data? capabilities]) async =>
(capabilities ?? (await getCapabilities()).ocs.data).version.major == 25; (capabilities ?? (await getCapabilities()).ocs.data).version.major == 25;
} }
// ignore: public_member_api_docs // ignore: public_member_api_docs
extension NewsVersionSupported on NewsClient { extension NewsVersionSupported on NextcloudNewsClient {
/// Checks if the app on the server is supported by the client /// Checks if the app on the server is supported by the client
Future<bool> isSupported() async { Future<bool> isSupported() async {
final versions = await getSupportedApiVersions(); final versions = await getSupportedApiVersions();
@ -17,9 +17,9 @@ extension NewsVersionSupported on NewsClient {
} }
// ignore: public_member_api_docs // ignore: public_member_api_docs
extension NotesVersionSupported on NotesClient { extension NotesVersionSupported on NextcloudNotesClient {
/// Checks if the app on the server is supported by the client /// Checks if the app on the server is supported by the client
Future<bool> isSupported([final CoreServerCapabilities_Ocs_Data? capabilities]) async => Future<bool> isSupported([final NextcloudCoreServerCapabilities_Ocs_Data? capabilities]) async =>
(capabilities ?? (await rootClient.core.getCapabilities()).ocs.data) (capabilities ?? (await rootClient.core.getCapabilities()).ocs.data)
.capabilities .capabilities
.notes .notes

4
packages/nextcloud/lib/src/webdav/client.dart

@ -9,7 +9,7 @@ class WebDavClient {
); );
// ignore: public_member_api_docs // ignore: public_member_api_docs
final Client rootClient; final NextcloudClient rootClient;
/// Base path used on the server /// Base path used on the server
final String basePath; final String basePath;
@ -54,7 +54,7 @@ class WebDavClient {
final response = await request.close(); final response = await request.close();
if (!expectedCodes.contains(response.statusCode)) { if (!expectedCodes.contains(response.statusCode)) {
throw ApiException( throw NextcloudApiException(
response.statusCode, response.statusCode,
{}, // TODO {}, // TODO
await response.bodyBytes, await response.bodyBytes,

4
packages/nextcloud/test/news.dart

@ -20,12 +20,12 @@ Future run(final DockerImage image) async {
}); });
tearDown(() => container.destroy()); tearDown(() => container.destroy());
Future<NewsListFeeds> addWikipediaFeed([final int? folderID]) => client.news.addFeed( Future<NextcloudNewsListFeeds> addWikipediaFeed([final int? folderID]) => client.news.addFeed(
url: wikipediaFeedURL, url: wikipediaFeedURL,
folderId: folderID, folderId: folderID,
); );
Future<NewsListFeeds> addNasaFeed() => client.news.addFeed( Future<NextcloudNewsListFeeds> addNasaFeed() => client.news.addFeed(
url: nasaFeedURL, url: nasaFeedURL,
); );

12
packages/nextcloud/test/notes.dart

@ -96,7 +96,7 @@ Future run(final DockerImage image) async {
title: 'c', title: 'c',
ifMatch: '"${response.etag}"', ifMatch: '"${response.etag}"',
), ),
throwsA(predicate((final e) => (e! as ApiException).statusCode == 412)), throwsA(predicate((final e) => (e! as NextcloudApiException).statusCode == 412)),
); );
}); });
@ -116,25 +116,25 @@ Future run(final DockerImage image) async {
final response = await client.notes.getSettings(); final response = await client.notes.getSettings();
expect(response.notesPath, 'Notes'); expect(response.notesPath, 'Notes');
expect(response.fileSuffix, '.txt'); expect(response.fileSuffix, '.txt');
expect(response.noteMode, NotesSettings_NoteMode.edit); expect(response.noteMode, NextcloudNotesSettings_NoteMode.edit);
}); });
test('Update settings', () async { test('Update settings', () async {
var response = await client.notes.updateSettings( var response = await client.notes.updateSettings(
notesSettings: NotesSettings( notesSettings: NextcloudNotesSettings(
notesPath: 'Test Notes', notesPath: 'Test Notes',
fileSuffix: '.md', fileSuffix: '.md',
noteMode: NotesSettings_NoteMode.preview, noteMode: NextcloudNotesSettings_NoteMode.preview,
), ),
); );
expect(response.notesPath, 'Test Notes'); expect(response.notesPath, 'Test Notes');
expect(response.fileSuffix, '.md'); expect(response.fileSuffix, '.md');
expect(response.noteMode, NotesSettings_NoteMode.preview); expect(response.noteMode, NextcloudNotesSettings_NoteMode.preview);
response = await client.notes.getSettings(); response = await client.notes.getSettings();
expect(response.notesPath, 'Test Notes'); expect(response.notesPath, 'Test Notes');
expect(response.fileSuffix, '.md'); expect(response.fileSuffix, '.md');
expect(response.noteMode, NotesSettings_NoteMode.preview); expect(response.noteMode, NextcloudNotesSettings_NoteMode.preview);
}); });
}); });
} }

38
packages/nextcloud/test/user_status.dart

@ -29,20 +29,20 @@ Future run(final DockerImage image) async {
} }
final meeting = response.ocs.data.singleWhere((final s) => s.id == 'meeting').clearAt.userStatusClearAt!; final meeting = response.ocs.data.singleWhere((final s) => s.id == 'meeting').clearAt.userStatusClearAt!;
expect(meeting.type, UserStatusClearAt_Type.period); expect(meeting.type, NextcloudUserStatusClearAt_Type.period);
expect(meeting.time.$int, 3600); expect(meeting.time.$int, 3600);
final commuting = response.ocs.data.singleWhere((final s) => s.id == 'commuting').clearAt.userStatusClearAt!; final commuting = response.ocs.data.singleWhere((final s) => s.id == 'commuting').clearAt.userStatusClearAt!;
expect(commuting.type, UserStatusClearAt_Type.period); expect(commuting.type, NextcloudUserStatusClearAt_Type.period);
expect(commuting.time.$int, 1800); expect(commuting.time.$int, 1800);
final remoteWork = response.ocs.data.singleWhere((final s) => s.id == 'remote-work').clearAt.userStatusClearAt!; final remoteWork = response.ocs.data.singleWhere((final s) => s.id == 'remote-work').clearAt.userStatusClearAt!;
expect(remoteWork.type, UserStatusClearAt_Type.endOf); expect(remoteWork.type, NextcloudUserStatusClearAt_Type.endOf);
expect(remoteWork.time.userStatusClearAtTime0, UserStatusClearAt_Time0.day); expect(remoteWork.time.userStatusClearAtTime0, NextcloudUserStatusClearAt_Time0.day);
final sickLeave = response.ocs.data.singleWhere((final s) => s.id == 'sick-leave').clearAt.userStatusClearAt!; final sickLeave = response.ocs.data.singleWhere((final s) => s.id == 'sick-leave').clearAt.userStatusClearAt!;
expect(sickLeave.type, UserStatusClearAt_Type.endOf); expect(sickLeave.type, NextcloudUserStatusClearAt_Type.endOf);
expect(sickLeave.time.userStatusClearAtTime0, UserStatusClearAt_Time0.day); expect(sickLeave.time.userStatusClearAtTime0, NextcloudUserStatusClearAt_Time0.day);
final vacationing = response.ocs.data.singleWhere((final s) => s.id == 'vacationing').clearAt; final vacationing = response.ocs.data.singleWhere((final s) => s.id == 'vacationing').clearAt;
expect(vacationing.userStatusClearAt, null); expect(vacationing.userStatusClearAt, null);
@ -50,7 +50,7 @@ Future run(final DockerImage image) async {
}); });
test('Set status', () async { test('Set status', () async {
final response = await client.userStatus.setStatus(statusType: UserStatusType.online); final response = await client.userStatus.setStatus(statusType: NextcloudUserStatusType.online);
expect(response.ocs.data.userStatus!.userId, 'user1'); expect(response.ocs.data.userStatus!.userId, 'user1');
expect(response.ocs.data.userStatus!.message, null); expect(response.ocs.data.userStatus!.message, null);
@ -59,14 +59,14 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatus!.icon, null); expect(response.ocs.data.userStatus!.icon, null);
expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null); expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null);
expect(response.ocs.data.userStatus!.clearAt.$int, null); expect(response.ocs.data.userStatus!.clearAt.$int, null);
expect(response.ocs.data.userStatus!.status, UserStatusType.online); expect(response.ocs.data.userStatus!.status, NextcloudUserStatusType.online);
expect(response.ocs.data.userStatus!.statusIsUserDefined, true); expect(response.ocs.data.userStatus!.statusIsUserDefined, true);
}); });
test('Get status', () async { test('Get status', () async {
// There seems to be a bug in Nextcloud which makes getting the status fail before it has been set once. // There seems to be a bug in Nextcloud which makes getting the status fail before it has been set once.
// The error message from Nextcloud is "Could not create folder" // The error message from Nextcloud is "Could not create folder"
await client.userStatus.setStatus(statusType: UserStatusType.online); await client.userStatus.setStatus(statusType: NextcloudUserStatusType.online);
final response = await client.userStatus.getStatus(); final response = await client.userStatus.getStatus();
expect(response.ocs.data.userStatus!.userId, 'user1'); expect(response.ocs.data.userStatus!.userId, 'user1');
@ -76,7 +76,7 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatus!.icon, null); expect(response.ocs.data.userStatus!.icon, null);
expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null); expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null);
expect(response.ocs.data.userStatus!.clearAt.$int, null); expect(response.ocs.data.userStatus!.clearAt.$int, null);
expect(response.ocs.data.userStatus!.status, UserStatusType.online); expect(response.ocs.data.userStatus!.status, NextcloudUserStatusType.online);
expect(response.ocs.data.userStatus!.statusIsUserDefined, true); expect(response.ocs.data.userStatus!.statusIsUserDefined, true);
}); });
@ -84,7 +84,7 @@ Future run(final DockerImage image) async {
var response = await client.userStatus.findAllStatuses(); var response = await client.userStatus.findAllStatuses();
expect(response.ocs.data, hasLength(0)); expect(response.ocs.data, hasLength(0));
await client.userStatus.setStatus(statusType: UserStatusType.online); await client.userStatus.setStatus(statusType: NextcloudUserStatusType.online);
response = await client.userStatus.findAllStatuses(); response = await client.userStatus.findAllStatuses();
expect(response.ocs.data, hasLength(1)); expect(response.ocs.data, hasLength(1));
@ -93,12 +93,12 @@ Future run(final DockerImage image) async {
expect(response.ocs.data[0].icon, null); expect(response.ocs.data[0].icon, null);
expect(response.ocs.data[0].clearAt.userStatusClearAt, null); expect(response.ocs.data[0].clearAt.userStatusClearAt, null);
expect(response.ocs.data[0].clearAt.$int, null); expect(response.ocs.data[0].clearAt.$int, null);
expect(response.ocs.data[0].status, UserStatusType.online); expect(response.ocs.data[0].status, NextcloudUserStatusType.online);
}); });
test('Find status', () async { test('Find status', () async {
// Same as getting status // Same as getting status
await client.userStatus.setStatus(statusType: UserStatusType.online); await client.userStatus.setStatus(statusType: NextcloudUserStatusType.online);
final response = await client.userStatus.findStatus(userId: 'user1'); final response = await client.userStatus.findStatus(userId: 'user1');
expect(response.ocs.data.userStatusPublicUserStatus!.userId, 'user1'); expect(response.ocs.data.userStatusPublicUserStatus!.userId, 'user1');
@ -106,7 +106,7 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatusPublicUserStatus!.icon, null); expect(response.ocs.data.userStatusPublicUserStatus!.icon, null);
expect(response.ocs.data.userStatusPublicUserStatus!.clearAt.userStatusClearAt, null); expect(response.ocs.data.userStatusPublicUserStatus!.clearAt.userStatusClearAt, null);
expect(response.ocs.data.userStatusPublicUserStatus!.clearAt.$int, null); expect(response.ocs.data.userStatusPublicUserStatus!.clearAt.$int, null);
expect(response.ocs.data.userStatusPublicUserStatus!.status, UserStatusType.online); expect(response.ocs.data.userStatusPublicUserStatus!.status, NextcloudUserStatusType.online);
}); });
test('Set predefined message', () async { test('Set predefined message', () async {
@ -121,7 +121,7 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatus!.messageIsPredefined, true); expect(response.ocs.data.userStatus!.messageIsPredefined, true);
expect(response.ocs.data.userStatus!.icon, null); expect(response.ocs.data.userStatus!.icon, null);
expect(response.ocs.data.userStatus!.clearAt.$int, clearAt); expect(response.ocs.data.userStatus!.clearAt.$int, clearAt);
expect(response.ocs.data.userStatus!.status, UserStatusType.offline); expect(response.ocs.data.userStatus!.status, NextcloudUserStatusType.offline);
expect(response.ocs.data.userStatus!.statusIsUserDefined, false); expect(response.ocs.data.userStatus!.statusIsUserDefined, false);
}); });
@ -138,7 +138,7 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatus!.messageIsPredefined, false); expect(response.ocs.data.userStatus!.messageIsPredefined, false);
expect(response.ocs.data.userStatus!.icon, '😀'); expect(response.ocs.data.userStatus!.icon, '😀');
expect(response.ocs.data.userStatus!.clearAt.$int, clearAt); expect(response.ocs.data.userStatus!.clearAt.$int, clearAt);
expect(response.ocs.data.userStatus!.status, UserStatusType.offline); expect(response.ocs.data.userStatus!.status, NextcloudUserStatusType.offline);
expect(response.ocs.data.userStatus!.statusIsUserDefined, false); expect(response.ocs.data.userStatus!.statusIsUserDefined, false);
}); });
@ -159,12 +159,12 @@ Future run(final DockerImage image) async {
expect(response.ocs.data.userStatus!.icon, null); expect(response.ocs.data.userStatus!.icon, null);
expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null); expect(response.ocs.data.userStatus!.clearAt.userStatusClearAt, null);
expect(response.ocs.data.userStatus!.clearAt.$int, null); expect(response.ocs.data.userStatus!.clearAt.$int, null);
expect(response.ocs.data.userStatus!.status, UserStatusType.offline); expect(response.ocs.data.userStatus!.status, NextcloudUserStatusType.offline);
expect(response.ocs.data.userStatus!.statusIsUserDefined, false); expect(response.ocs.data.userStatus!.statusIsUserDefined, false);
}); });
test('Heartbeat', () async { test('Heartbeat', () async {
final response = await client.userStatus.heartbeat(status: UserStatusType.online); final response = await client.userStatus.heartbeat(status: NextcloudUserStatusType.online);
expect(response.userId, 'user1'); expect(response.userId, 'user1');
expect(response.message, null); expect(response.message, null);
expect(response.messageId, null); expect(response.messageId, null);
@ -172,7 +172,7 @@ Future run(final DockerImage image) async {
expect(response.icon, null); expect(response.icon, null);
expect(response.clearAt.userStatusClearAt, null); expect(response.clearAt.userStatusClearAt, null);
expect(response.clearAt.$int, null); expect(response.clearAt.$int, null);
expect(response.status, UserStatusType.online); expect(response.status, NextcloudUserStatusType.online);
expect(response.statusIsUserDefined, false); expect(response.statusIsUserDefined, false);
}); });
}); });

4
packages/nextcloud/test/webdav.dart

@ -107,7 +107,7 @@ Future run(final DockerImage image) async {
expect( expect(
() => client.webdav.copy('1.txt', '2.txt'), () => client.webdav.copy('1.txt', '2.txt'),
throwsA(predicate((final e) => (e! as ApiException).statusCode == 412)), throwsA(predicate((final e) => (e! as NextcloudApiException).statusCode == 412)),
); );
}); });
@ -140,7 +140,7 @@ Future run(final DockerImage image) async {
expect( expect(
() => client.webdav.move('1.txt', '2.txt'), () => client.webdav.move('1.txt', '2.txt'),
throwsA(predicate((final e) => (e! as ApiException).statusCode == 412)), throwsA(predicate((final e) => (e! as NextcloudApiException).statusCode == 412)),
); );
}); });

Loading…
Cancel
Save