Compare commits
7 Commits
f03f0181f8
...
3.0.0+110
Author | SHA1 | Date | |
---|---|---|---|
007acedf29 | |||
8e903ec6c1 | |||
b55e56c3c4 | |||
6f9de431b1 | |||
a8efd26262 | |||
e367fc3f5c | |||
8a1af120ea |
@ -675,5 +675,8 @@
|
|||||||
"publisherFeatureDevelop": "Developer Program",
|
"publisherFeatureDevelop": "Developer Program",
|
||||||
"publisherFeatureDevelopDescription": "Unlock development abilities for your publisher, including custom apps, API keys, and more.",
|
"publisherFeatureDevelopDescription": "Unlock development abilities for your publisher, including custom apps, API keys, and more.",
|
||||||
"publisherFeatureDevelopHint": "Currently, this feature is under active development, you need send a request to unlock this feature.",
|
"publisherFeatureDevelopHint": "Currently, this feature is under active development, you need send a request to unlock this feature.",
|
||||||
"learnMore": "Learn More"
|
"learnMore": "Learn More",
|
||||||
|
"discoverWebArticles": "Articles from external sites",
|
||||||
|
"webArticlesStand": "Article Stand",
|
||||||
|
"about": "About"
|
||||||
}
|
}
|
||||||
|
@ -40,31 +40,31 @@ PODS:
|
|||||||
- file_picker (0.0.1):
|
- file_picker (0.0.1):
|
||||||
- DKImagePickerController/PhotoGallery
|
- DKImagePickerController/PhotoGallery
|
||||||
- Flutter
|
- Flutter
|
||||||
- Firebase/CoreOnly (11.13.0):
|
- Firebase/CoreOnly (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- Firebase/Messaging (11.13.0):
|
- Firebase/Messaging (11.15.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 11.13.0)
|
- FirebaseMessaging (~> 11.15.0)
|
||||||
- firebase_core (3.14.0):
|
- firebase_core (3.15.0):
|
||||||
- Firebase/CoreOnly (= 11.13.0)
|
- Firebase/CoreOnly (= 11.15.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_messaging (15.2.7):
|
- firebase_messaging (15.2.8):
|
||||||
- Firebase/Messaging (= 11.13.0)
|
- Firebase/Messaging (= 11.15.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- FirebaseCore (11.13.0):
|
- FirebaseCore (11.15.0):
|
||||||
- FirebaseCoreInternal (~> 11.13.0)
|
- FirebaseCoreInternal (~> 11.15.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
- FirebaseCoreInternal (11.13.0):
|
- FirebaseCoreInternal (11.15.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- FirebaseInstallations (11.13.0):
|
- FirebaseInstallations (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseMessaging (11.13.0):
|
- FirebaseMessaging (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- FirebaseInstallations (~> 11.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleDataTransport (~> 10.0)
|
- GoogleDataTransport (~> 10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
@ -80,6 +80,8 @@ PODS:
|
|||||||
- flutter_inappwebview_ios/Core (0.0.1):
|
- flutter_inappwebview_ios/Core (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- OrderedSet (~> 6.0.3)
|
- OrderedSet (~> 6.0.3)
|
||||||
|
- flutter_keyboard_visibility (0.0.1):
|
||||||
|
- Flutter
|
||||||
- flutter_native_splash (2.4.3):
|
- flutter_native_splash (2.4.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_platform_alert (0.0.1):
|
- flutter_platform_alert (0.0.1):
|
||||||
@ -128,8 +130,8 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- irondash_engine_context (0.0.1):
|
- irondash_engine_context (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Kingfisher (8.3.2)
|
- Kingfisher (8.3.3)
|
||||||
- livekit_client (2.4.8):
|
- livekit_client (2.4.9):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_webrtc
|
- flutter_webrtc
|
||||||
- WebRTC-SDK (= 125.6422.07)
|
- WebRTC-SDK (= 125.6422.07)
|
||||||
@ -155,6 +157,8 @@ PODS:
|
|||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- pointer_interceptor_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
- PromisesObjC (2.4.0)
|
- PromisesObjC (2.4.0)
|
||||||
- receive_sharing_intent (1.8.1):
|
- receive_sharing_intent (1.8.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@ -217,6 +221,7 @@ DEPENDENCIES:
|
|||||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
|
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
|
||||||
|
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||||
- flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`)
|
- flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`)
|
||||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||||
@ -235,6 +240,7 @@ DEPENDENCIES:
|
|||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- pasteboard (from `.symlinks/plugins/pasteboard/ios`)
|
- pasteboard (from `.symlinks/plugins/pasteboard/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
|
- pointer_interceptor_ios (from `.symlinks/plugins/pointer_interceptor_ios/ios`)
|
||||||
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||||
- record_ios (from `.symlinks/plugins/record_ios/ios`)
|
- record_ios (from `.symlinks/plugins/record_ios/ios`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
@ -286,6 +292,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter
|
:path: Flutter
|
||||||
flutter_inappwebview_ios:
|
flutter_inappwebview_ios:
|
||||||
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
|
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
|
||||||
|
flutter_keyboard_visibility:
|
||||||
|
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||||
flutter_platform_alert:
|
flutter_platform_alert:
|
||||||
@ -320,6 +328,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/pasteboard/ios"
|
:path: ".symlinks/plugins/pasteboard/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
|
pointer_interceptor_ios:
|
||||||
|
:path: ".symlinks/plugins/pointer_interceptor_ios/ios"
|
||||||
receive_sharing_intent:
|
receive_sharing_intent:
|
||||||
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||||
record_ios:
|
record_ios:
|
||||||
@ -351,15 +361,16 @@ SPEC CHECKSUMS:
|
|||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||||
Firebase: 3435bc66b4d494c2f22c79fd3aae4c1db6662327
|
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
|
||||||
firebase_core: 700bac7ed92bb754fd70fbf01d72b36ecdd6d450
|
firebase_core: c727a02c560a53f1f1e56e18f16515eb5753c492
|
||||||
firebase_messaging: 860c017fcfbb5e27c163062d1d3135388f3ef954
|
firebase_messaging: 4158969b04b667f5435731ec9d6e453bb58b0c4c
|
||||||
FirebaseCore: c692c7f1c75305ab6aff2b367f25e11d73aa8bd0
|
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
|
||||||
FirebaseCoreInternal: 29d7b3af4aaf0b8f3ed20b568c13df399b06f68c
|
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
|
||||||
FirebaseInstallations: 0ee9074f2c1e86561ace168ee1470dc67aabaf02
|
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
|
||||||
FirebaseMessaging: 195bbdb73e6ca1dbc76cd46e73f3552c084ef6e4
|
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||||
|
flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619
|
||||||
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
|
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
|
||||||
flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3
|
flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3
|
||||||
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
||||||
@ -371,8 +382,8 @@ SPEC CHECKSUMS:
|
|||||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||||
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
|
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
|
||||||
Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5
|
Kingfisher: ff82cb91d9266ddb56cbb2f72d32c26f00d3e5be
|
||||||
livekit_client: 9e901890552514206e5ff828903ed271531da264
|
livekit_client: 3f79d79233a5bd13d5b541732624ef959d7c538e
|
||||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||||
@ -382,6 +393,7 @@ SPEC CHECKSUMS:
|
|||||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||||
pasteboard: 49088aeb6119d51f976a421db60d8e1ab079b63c
|
pasteboard: 49088aeb6119d51f976a421db60d8e1ab079b63c
|
||||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||||
|
pointer_interceptor_ios: ec847ef8b0915778bed2b2cef636f4d177fa8eed
|
||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||||
record_ios: fee1c924aa4879b882ebca2b4bce6011bcfc3d8b
|
record_ios: fee1c924aa4879b882ebca2b4bce6011bcfc3d8b
|
||||||
|
34
lib/models/auto_completion.dart
Normal file
34
lib/models/auto_completion.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'auto_completion.freezed.dart';
|
||||||
|
part 'auto_completion.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class AutoCompletionResponse with _$AutoCompletionResponse {
|
||||||
|
const factory AutoCompletionResponse.account({
|
||||||
|
required String type,
|
||||||
|
required List<AutoCompletionItem> items,
|
||||||
|
}) = AutoCompletionAccountResponse;
|
||||||
|
|
||||||
|
const factory AutoCompletionResponse.sticker({
|
||||||
|
required String type,
|
||||||
|
required List<AutoCompletionItem> items,
|
||||||
|
}) = AutoCompletionStickerResponse;
|
||||||
|
|
||||||
|
factory AutoCompletionResponse.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AutoCompletionResponseFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class AutoCompletionItem with _$AutoCompletionItem {
|
||||||
|
const factory AutoCompletionItem({
|
||||||
|
required String id,
|
||||||
|
required String displayName,
|
||||||
|
required String? secondaryText,
|
||||||
|
required String type,
|
||||||
|
required dynamic data,
|
||||||
|
}) = _AutoCompletionItem;
|
||||||
|
|
||||||
|
factory AutoCompletionItem.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AutoCompletionItemFromJson(json);
|
||||||
|
}
|
410
lib/models/auto_completion.freezed.dart
Normal file
410
lib/models/auto_completion.freezed.dart
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'auto_completion.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
AutoCompletionResponse _$AutoCompletionResponseFromJson(
|
||||||
|
Map<String, dynamic> json
|
||||||
|
) {
|
||||||
|
switch (json['runtimeType']) {
|
||||||
|
case 'account':
|
||||||
|
return AutoCompletionAccountResponse.fromJson(
|
||||||
|
json
|
||||||
|
);
|
||||||
|
case 'sticker':
|
||||||
|
return AutoCompletionStickerResponse.fromJson(
|
||||||
|
json
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw CheckedFromJsonException(
|
||||||
|
json,
|
||||||
|
'runtimeType',
|
||||||
|
'AutoCompletionResponse',
|
||||||
|
'Invalid union type "${json['runtimeType']}"!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AutoCompletionResponse {
|
||||||
|
|
||||||
|
String get type; List<AutoCompletionItem> get items;
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AutoCompletionResponseCopyWith<AutoCompletionResponse> get copyWith => _$AutoCompletionResponseCopyWithImpl<AutoCompletionResponse>(this as AutoCompletionResponse, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this AutoCompletionResponse to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AutoCompletionResponse&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.items, items));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(items));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AutoCompletionResponse(type: $type, items: $items)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $AutoCompletionResponseCopyWith<$Res> {
|
||||||
|
factory $AutoCompletionResponseCopyWith(AutoCompletionResponse value, $Res Function(AutoCompletionResponse) _then) = _$AutoCompletionResponseCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String type, List<AutoCompletionItem> items
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$AutoCompletionResponseCopyWithImpl<$Res>
|
||||||
|
implements $AutoCompletionResponseCopyWith<$Res> {
|
||||||
|
_$AutoCompletionResponseCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final AutoCompletionResponse _self;
|
||||||
|
final $Res Function(AutoCompletionResponse) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? items = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<AutoCompletionItem>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class AutoCompletionAccountResponse implements AutoCompletionResponse {
|
||||||
|
const AutoCompletionAccountResponse({required this.type, required final List<AutoCompletionItem> items, final String? $type}): _items = items,$type = $type ?? 'account';
|
||||||
|
factory AutoCompletionAccountResponse.fromJson(Map<String, dynamic> json) => _$AutoCompletionAccountResponseFromJson(json);
|
||||||
|
|
||||||
|
@override final String type;
|
||||||
|
final List<AutoCompletionItem> _items;
|
||||||
|
@override List<AutoCompletionItem> get items {
|
||||||
|
if (_items is EqualUnmodifiableListView) return _items;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AutoCompletionAccountResponseCopyWith<AutoCompletionAccountResponse> get copyWith => _$AutoCompletionAccountResponseCopyWithImpl<AutoCompletionAccountResponse>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$AutoCompletionAccountResponseToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AutoCompletionAccountResponse&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._items, _items));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(_items));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AutoCompletionResponse.account(type: $type, items: $items)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $AutoCompletionAccountResponseCopyWith<$Res> implements $AutoCompletionResponseCopyWith<$Res> {
|
||||||
|
factory $AutoCompletionAccountResponseCopyWith(AutoCompletionAccountResponse value, $Res Function(AutoCompletionAccountResponse) _then) = _$AutoCompletionAccountResponseCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String type, List<AutoCompletionItem> items
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$AutoCompletionAccountResponseCopyWithImpl<$Res>
|
||||||
|
implements $AutoCompletionAccountResponseCopyWith<$Res> {
|
||||||
|
_$AutoCompletionAccountResponseCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final AutoCompletionAccountResponse _self;
|
||||||
|
final $Res Function(AutoCompletionAccountResponse) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? items = null,}) {
|
||||||
|
return _then(AutoCompletionAccountResponse(
|
||||||
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<AutoCompletionItem>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class AutoCompletionStickerResponse implements AutoCompletionResponse {
|
||||||
|
const AutoCompletionStickerResponse({required this.type, required final List<AutoCompletionItem> items, final String? $type}): _items = items,$type = $type ?? 'sticker';
|
||||||
|
factory AutoCompletionStickerResponse.fromJson(Map<String, dynamic> json) => _$AutoCompletionStickerResponseFromJson(json);
|
||||||
|
|
||||||
|
@override final String type;
|
||||||
|
final List<AutoCompletionItem> _items;
|
||||||
|
@override List<AutoCompletionItem> get items {
|
||||||
|
if (_items is EqualUnmodifiableListView) return _items;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AutoCompletionStickerResponseCopyWith<AutoCompletionStickerResponse> get copyWith => _$AutoCompletionStickerResponseCopyWithImpl<AutoCompletionStickerResponse>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$AutoCompletionStickerResponseToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AutoCompletionStickerResponse&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._items, _items));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(_items));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AutoCompletionResponse.sticker(type: $type, items: $items)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $AutoCompletionStickerResponseCopyWith<$Res> implements $AutoCompletionResponseCopyWith<$Res> {
|
||||||
|
factory $AutoCompletionStickerResponseCopyWith(AutoCompletionStickerResponse value, $Res Function(AutoCompletionStickerResponse) _then) = _$AutoCompletionStickerResponseCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String type, List<AutoCompletionItem> items
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$AutoCompletionStickerResponseCopyWithImpl<$Res>
|
||||||
|
implements $AutoCompletionStickerResponseCopyWith<$Res> {
|
||||||
|
_$AutoCompletionStickerResponseCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final AutoCompletionStickerResponse _self;
|
||||||
|
final $Res Function(AutoCompletionStickerResponse) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? items = null,}) {
|
||||||
|
return _then(AutoCompletionStickerResponse(
|
||||||
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<AutoCompletionItem>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AutoCompletionItem {
|
||||||
|
|
||||||
|
String get id; String get displayName; String? get secondaryText; String get type; dynamic get data;
|
||||||
|
/// Create a copy of AutoCompletionItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AutoCompletionItemCopyWith<AutoCompletionItem> get copyWith => _$AutoCompletionItemCopyWithImpl<AutoCompletionItem>(this as AutoCompletionItem, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this AutoCompletionItem to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AutoCompletionItem&&(identical(other.id, id) || other.id == id)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.secondaryText, secondaryText) || other.secondaryText == secondaryText)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.data, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,displayName,secondaryText,type,const DeepCollectionEquality().hash(data));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AutoCompletionItem(id: $id, displayName: $displayName, secondaryText: $secondaryText, type: $type, data: $data)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $AutoCompletionItemCopyWith<$Res> {
|
||||||
|
factory $AutoCompletionItemCopyWith(AutoCompletionItem value, $Res Function(AutoCompletionItem) _then) = _$AutoCompletionItemCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String id, String displayName, String? secondaryText, String type, dynamic data
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$AutoCompletionItemCopyWithImpl<$Res>
|
||||||
|
implements $AutoCompletionItemCopyWith<$Res> {
|
||||||
|
_$AutoCompletionItemCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final AutoCompletionItem _self;
|
||||||
|
final $Res Function(AutoCompletionItem) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? displayName = null,Object? secondaryText = freezed,Object? type = null,Object? data = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,secondaryText: freezed == secondaryText ? _self.secondaryText : secondaryText // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _AutoCompletionItem implements AutoCompletionItem {
|
||||||
|
const _AutoCompletionItem({required this.id, required this.displayName, required this.secondaryText, required this.type, required this.data});
|
||||||
|
factory _AutoCompletionItem.fromJson(Map<String, dynamic> json) => _$AutoCompletionItemFromJson(json);
|
||||||
|
|
||||||
|
@override final String id;
|
||||||
|
@override final String displayName;
|
||||||
|
@override final String? secondaryText;
|
||||||
|
@override final String type;
|
||||||
|
@override final dynamic data;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$AutoCompletionItemCopyWith<_AutoCompletionItem> get copyWith => __$AutoCompletionItemCopyWithImpl<_AutoCompletionItem>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$AutoCompletionItemToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AutoCompletionItem&&(identical(other.id, id) || other.id == id)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.secondaryText, secondaryText) || other.secondaryText == secondaryText)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.data, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,displayName,secondaryText,type,const DeepCollectionEquality().hash(data));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AutoCompletionItem(id: $id, displayName: $displayName, secondaryText: $secondaryText, type: $type, data: $data)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$AutoCompletionItemCopyWith<$Res> implements $AutoCompletionItemCopyWith<$Res> {
|
||||||
|
factory _$AutoCompletionItemCopyWith(_AutoCompletionItem value, $Res Function(_AutoCompletionItem) _then) = __$AutoCompletionItemCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String id, String displayName, String? secondaryText, String type, dynamic data
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$AutoCompletionItemCopyWithImpl<$Res>
|
||||||
|
implements _$AutoCompletionItemCopyWith<$Res> {
|
||||||
|
__$AutoCompletionItemCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _AutoCompletionItem _self;
|
||||||
|
final $Res Function(_AutoCompletionItem) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AutoCompletionItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? displayName = null,Object? secondaryText = freezed,Object? type = null,Object? data = freezed,}) {
|
||||||
|
return _then(_AutoCompletionItem(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,secondaryText: freezed == secondaryText ? _self.secondaryText : secondaryText // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
63
lib/models/auto_completion.g.dart
Normal file
63
lib/models/auto_completion.g.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'auto_completion.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
AutoCompletionAccountResponse _$AutoCompletionAccountResponseFromJson(
|
||||||
|
Map<String, dynamic> json,
|
||||||
|
) => AutoCompletionAccountResponse(
|
||||||
|
type: json['type'] as String,
|
||||||
|
items:
|
||||||
|
(json['items'] as List<dynamic>)
|
||||||
|
.map((e) => AutoCompletionItem.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AutoCompletionAccountResponseToJson(
|
||||||
|
AutoCompletionAccountResponse instance,
|
||||||
|
) => <String, dynamic>{
|
||||||
|
'type': instance.type,
|
||||||
|
'items': instance.items.map((e) => e.toJson()).toList(),
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
AutoCompletionStickerResponse _$AutoCompletionStickerResponseFromJson(
|
||||||
|
Map<String, dynamic> json,
|
||||||
|
) => AutoCompletionStickerResponse(
|
||||||
|
type: json['type'] as String,
|
||||||
|
items:
|
||||||
|
(json['items'] as List<dynamic>)
|
||||||
|
.map((e) => AutoCompletionItem.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AutoCompletionStickerResponseToJson(
|
||||||
|
AutoCompletionStickerResponse instance,
|
||||||
|
) => <String, dynamic>{
|
||||||
|
'type': instance.type,
|
||||||
|
'items': instance.items.map((e) => e.toJson()).toList(),
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_AutoCompletionItem _$AutoCompletionItemFromJson(Map<String, dynamic> json) =>
|
||||||
|
_AutoCompletionItem(
|
||||||
|
id: json['id'] as String,
|
||||||
|
displayName: json['display_name'] as String,
|
||||||
|
secondaryText: json['secondary_text'] as String?,
|
||||||
|
type: json['type'] as String,
|
||||||
|
data: json['data'],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AutoCompletionItemToJson(_AutoCompletionItem instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'display_name': instance.displayName,
|
||||||
|
'secondary_text': instance.secondaryText,
|
||||||
|
'type': instance.type,
|
||||||
|
'data': instance.data,
|
||||||
|
};
|
@ -7,57 +7,58 @@ part 'webfeed.freezed.dart';
|
|||||||
part 'webfeed.g.dart';
|
part 'webfeed.g.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class WebFeedConfig with _$WebFeedConfig {
|
sealed class SnWebFeedConfig with _$SnWebFeedConfig {
|
||||||
const factory WebFeedConfig({@Default(false) bool scrapPage}) =
|
const factory SnWebFeedConfig({@Default(false) bool scrapPage}) =
|
||||||
_WebFeedConfig;
|
_SnWebFeedConfig;
|
||||||
|
|
||||||
factory WebFeedConfig.fromJson(Map<String, dynamic> json) =>
|
factory SnWebFeedConfig.fromJson(Map<String, dynamic> json) =>
|
||||||
_$WebFeedConfigFromJson(json);
|
_$SnWebFeedConfigFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class WebFeed with _$WebFeed {
|
sealed class SnWebFeed with _$SnWebFeed {
|
||||||
const factory WebFeed({
|
const factory SnWebFeed({
|
||||||
required String id,
|
required String id,
|
||||||
required String url,
|
required String url,
|
||||||
required String title,
|
required String title,
|
||||||
String? description,
|
String? description,
|
||||||
SnScrappedLink? preview,
|
SnScrappedLink? preview,
|
||||||
@Default(WebFeedConfig()) WebFeedConfig config,
|
@Default(SnWebFeedConfig()) SnWebFeedConfig config,
|
||||||
required String publisherId,
|
required String publisherId,
|
||||||
@Default([]) List<WebArticle> articles,
|
@Default([]) List<SnWebArticle> articles,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
}) = _WebFeed;
|
}) = _SnWebFeed;
|
||||||
|
|
||||||
factory WebFeed.fromJson(Map<String, dynamic> json) =>
|
factory SnWebFeed.fromJson(Map<String, dynamic> json) =>
|
||||||
_$WebFeedFromJson(json);
|
_$SnWebFeedFromJson(json);
|
||||||
|
|
||||||
factory WebFeed.fromJsonString(String jsonString) =>
|
factory SnWebFeed.fromJsonString(String jsonString) =>
|
||||||
WebFeed.fromJson(jsonDecode(jsonString) as Map<String, dynamic>);
|
SnWebFeed.fromJson(jsonDecode(jsonString) as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class WebArticle with _$WebArticle {
|
sealed class SnWebArticle with _$SnWebArticle {
|
||||||
const factory WebArticle({
|
const factory SnWebArticle({
|
||||||
required String id,
|
required String id,
|
||||||
required String title,
|
required String title,
|
||||||
required String url,
|
required String url,
|
||||||
String? author,
|
String? author,
|
||||||
Map<String, dynamic>? meta,
|
Map<String, dynamic>? meta,
|
||||||
SnScrappedLink? preview,
|
SnScrappedLink? preview,
|
||||||
|
SnWebFeed? feed,
|
||||||
String? content,
|
String? content,
|
||||||
DateTime? publishedAt,
|
DateTime? publishedAt,
|
||||||
required String feedId,
|
required String feedId,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
}) = _WebArticle;
|
}) = _SnWebArticle;
|
||||||
|
|
||||||
factory WebArticle.fromJson(Map<String, dynamic> json) =>
|
factory SnWebArticle.fromJson(Map<String, dynamic> json) =>
|
||||||
_$WebArticleFromJson(json);
|
_$SnWebArticleFromJson(json);
|
||||||
|
|
||||||
factory WebArticle.fromJsonString(String jsonString) =>
|
factory SnWebArticle.fromJsonString(String jsonString) =>
|
||||||
WebArticle.fromJson(jsonDecode(jsonString) as Map<String, dynamic>);
|
SnWebArticle.fromJson(jsonDecode(jsonString) as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
|
@ -14,22 +14,22 @@ part of 'webfeed.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$WebFeedConfig {
|
mixin _$SnWebFeedConfig {
|
||||||
|
|
||||||
bool get scrapPage;
|
bool get scrapPage;
|
||||||
/// Create a copy of WebFeedConfig
|
/// Create a copy of SnWebFeedConfig
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$WebFeedConfigCopyWith<WebFeedConfig> get copyWith => _$WebFeedConfigCopyWithImpl<WebFeedConfig>(this as WebFeedConfig, _$identity);
|
$SnWebFeedConfigCopyWith<SnWebFeedConfig> get copyWith => _$SnWebFeedConfigCopyWithImpl<SnWebFeedConfig>(this as SnWebFeedConfig, _$identity);
|
||||||
|
|
||||||
/// Serializes this WebFeedConfig to a JSON map.
|
/// Serializes this SnWebFeedConfig to a JSON map.
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebFeedConfig&&(identical(other.scrapPage, scrapPage) || other.scrapPage == scrapPage));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnWebFeedConfig&&(identical(other.scrapPage, scrapPage) || other.scrapPage == scrapPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -38,15 +38,15 @@ int get hashCode => Object.hash(runtimeType,scrapPage);
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebFeedConfig(scrapPage: $scrapPage)';
|
return 'SnWebFeedConfig(scrapPage: $scrapPage)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class $WebFeedConfigCopyWith<$Res> {
|
abstract mixin class $SnWebFeedConfigCopyWith<$Res> {
|
||||||
factory $WebFeedConfigCopyWith(WebFeedConfig value, $Res Function(WebFeedConfig) _then) = _$WebFeedConfigCopyWithImpl;
|
factory $SnWebFeedConfigCopyWith(SnWebFeedConfig value, $Res Function(SnWebFeedConfig) _then) = _$SnWebFeedConfigCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool scrapPage
|
bool scrapPage
|
||||||
@ -57,14 +57,14 @@ $Res call({
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$WebFeedConfigCopyWithImpl<$Res>
|
class _$SnWebFeedConfigCopyWithImpl<$Res>
|
||||||
implements $WebFeedConfigCopyWith<$Res> {
|
implements $SnWebFeedConfigCopyWith<$Res> {
|
||||||
_$WebFeedConfigCopyWithImpl(this._self, this._then);
|
_$SnWebFeedConfigCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final WebFeedConfig _self;
|
final SnWebFeedConfig _self;
|
||||||
final $Res Function(WebFeedConfig) _then;
|
final $Res Function(SnWebFeedConfig) _then;
|
||||||
|
|
||||||
/// Create a copy of WebFeedConfig
|
/// Create a copy of SnWebFeedConfig
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? scrapPage = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? scrapPage = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
@ -79,26 +79,26 @@ as bool,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _WebFeedConfig implements WebFeedConfig {
|
class _SnWebFeedConfig implements SnWebFeedConfig {
|
||||||
const _WebFeedConfig({this.scrapPage = false});
|
const _SnWebFeedConfig({this.scrapPage = false});
|
||||||
factory _WebFeedConfig.fromJson(Map<String, dynamic> json) => _$WebFeedConfigFromJson(json);
|
factory _SnWebFeedConfig.fromJson(Map<String, dynamic> json) => _$SnWebFeedConfigFromJson(json);
|
||||||
|
|
||||||
@override@JsonKey() final bool scrapPage;
|
@override@JsonKey() final bool scrapPage;
|
||||||
|
|
||||||
/// Create a copy of WebFeedConfig
|
/// Create a copy of SnWebFeedConfig
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$WebFeedConfigCopyWith<_WebFeedConfig> get copyWith => __$WebFeedConfigCopyWithImpl<_WebFeedConfig>(this, _$identity);
|
_$SnWebFeedConfigCopyWith<_SnWebFeedConfig> get copyWith => __$SnWebFeedConfigCopyWithImpl<_SnWebFeedConfig>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$WebFeedConfigToJson(this, );
|
return _$SnWebFeedConfigToJson(this, );
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebFeedConfig&&(identical(other.scrapPage, scrapPage) || other.scrapPage == scrapPage));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnWebFeedConfig&&(identical(other.scrapPage, scrapPage) || other.scrapPage == scrapPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -107,15 +107,15 @@ int get hashCode => Object.hash(runtimeType,scrapPage);
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebFeedConfig(scrapPage: $scrapPage)';
|
return 'SnWebFeedConfig(scrapPage: $scrapPage)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class _$WebFeedConfigCopyWith<$Res> implements $WebFeedConfigCopyWith<$Res> {
|
abstract mixin class _$SnWebFeedConfigCopyWith<$Res> implements $SnWebFeedConfigCopyWith<$Res> {
|
||||||
factory _$WebFeedConfigCopyWith(_WebFeedConfig value, $Res Function(_WebFeedConfig) _then) = __$WebFeedConfigCopyWithImpl;
|
factory _$SnWebFeedConfigCopyWith(_SnWebFeedConfig value, $Res Function(_SnWebFeedConfig) _then) = __$SnWebFeedConfigCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool scrapPage
|
bool scrapPage
|
||||||
@ -126,17 +126,17 @@ $Res call({
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$WebFeedConfigCopyWithImpl<$Res>
|
class __$SnWebFeedConfigCopyWithImpl<$Res>
|
||||||
implements _$WebFeedConfigCopyWith<$Res> {
|
implements _$SnWebFeedConfigCopyWith<$Res> {
|
||||||
__$WebFeedConfigCopyWithImpl(this._self, this._then);
|
__$SnWebFeedConfigCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final _WebFeedConfig _self;
|
final _SnWebFeedConfig _self;
|
||||||
final $Res Function(_WebFeedConfig) _then;
|
final $Res Function(_SnWebFeedConfig) _then;
|
||||||
|
|
||||||
/// Create a copy of WebFeedConfig
|
/// Create a copy of SnWebFeedConfig
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? scrapPage = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? scrapPage = null,}) {
|
||||||
return _then(_WebFeedConfig(
|
return _then(_SnWebFeedConfig(
|
||||||
scrapPage: null == scrapPage ? _self.scrapPage : scrapPage // ignore: cast_nullable_to_non_nullable
|
scrapPage: null == scrapPage ? _self.scrapPage : scrapPage // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
));
|
));
|
||||||
@ -147,22 +147,22 @@ as bool,
|
|||||||
|
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$WebFeed {
|
mixin _$SnWebFeed {
|
||||||
|
|
||||||
String get id; String get url; String get title; String? get description; SnScrappedLink? get preview; WebFeedConfig get config; String get publisherId; List<WebArticle> get articles; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String get url; String get title; String? get description; SnScrappedLink? get preview; SnWebFeedConfig get config; String get publisherId; List<SnWebArticle> get articles; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$WebFeedCopyWith<WebFeed> get copyWith => _$WebFeedCopyWithImpl<WebFeed>(this as WebFeed, _$identity);
|
$SnWebFeedCopyWith<SnWebFeed> get copyWith => _$SnWebFeedCopyWithImpl<SnWebFeed>(this as SnWebFeed, _$identity);
|
||||||
|
|
||||||
/// Serializes this WebFeed to a JSON map.
|
/// Serializes this SnWebFeed to a JSON map.
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebFeed&&(identical(other.id, id) || other.id == id)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.config, config) || other.config == config)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&const DeepCollectionEquality().equals(other.articles, articles)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnWebFeed&&(identical(other.id, id) || other.id == id)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.config, config) || other.config == config)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&const DeepCollectionEquality().equals(other.articles, articles)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -171,33 +171,33 @@ int get hashCode => Object.hash(runtimeType,id,url,title,description,preview,con
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebFeed(id: $id, url: $url, title: $title, description: $description, preview: $preview, config: $config, publisherId: $publisherId, articles: $articles, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWebFeed(id: $id, url: $url, title: $title, description: $description, preview: $preview, config: $config, publisherId: $publisherId, articles: $articles, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class $WebFeedCopyWith<$Res> {
|
abstract mixin class $SnWebFeedCopyWith<$Res> {
|
||||||
factory $WebFeedCopyWith(WebFeed value, $Res Function(WebFeed) _then) = _$WebFeedCopyWithImpl;
|
factory $SnWebFeedCopyWith(SnWebFeed value, $Res Function(SnWebFeed) _then) = _$SnWebFeedCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String url, String title, String? description, SnScrappedLink? preview, WebFeedConfig config, String publisherId, List<WebArticle> articles, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String url, String title, String? description, SnScrappedLink? preview, SnWebFeedConfig config, String publisherId, List<SnWebArticle> articles, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$SnScrappedLinkCopyWith<$Res>? get preview;$WebFeedConfigCopyWith<$Res> get config;
|
$SnScrappedLinkCopyWith<$Res>? get preview;$SnWebFeedConfigCopyWith<$Res> get config;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$WebFeedCopyWithImpl<$Res>
|
class _$SnWebFeedCopyWithImpl<$Res>
|
||||||
implements $WebFeedCopyWith<$Res> {
|
implements $SnWebFeedCopyWith<$Res> {
|
||||||
_$WebFeedCopyWithImpl(this._self, this._then);
|
_$SnWebFeedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final WebFeed _self;
|
final SnWebFeed _self;
|
||||||
final $Res Function(WebFeed) _then;
|
final $Res Function(SnWebFeed) _then;
|
||||||
|
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? url = null,Object? title = null,Object? description = freezed,Object? preview = freezed,Object? config = null,Object? publisherId = null,Object? articles = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? url = null,Object? title = null,Object? description = freezed,Object? preview = freezed,Object? config = null,Object? publisherId = null,Object? articles = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
@ -207,15 +207,15 @@ as String,title: null == title ? _self.title : title // ignore: cast_nullable_to
|
|||||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
as String?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
as SnScrappedLink?,config: null == config ? _self.config : config // ignore: cast_nullable_to_non_nullable
|
as SnScrappedLink?,config: null == config ? _self.config : config // ignore: cast_nullable_to_non_nullable
|
||||||
as WebFeedConfig,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
as SnWebFeedConfig,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,articles: null == articles ? _self.articles : articles // ignore: cast_nullable_to_non_nullable
|
as String,articles: null == articles ? _self.articles : articles // ignore: cast_nullable_to_non_nullable
|
||||||
as List<WebArticle>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as List<SnWebArticle>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@ -227,13 +227,13 @@ $SnScrappedLinkCopyWith<$Res>? get preview {
|
|||||||
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
||||||
return _then(_self.copyWith(preview: value));
|
return _then(_self.copyWith(preview: value));
|
||||||
});
|
});
|
||||||
}/// Create a copy of WebFeed
|
}/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$WebFeedConfigCopyWith<$Res> get config {
|
$SnWebFeedConfigCopyWith<$Res> get config {
|
||||||
|
|
||||||
return $WebFeedConfigCopyWith<$Res>(_self.config, (value) {
|
return $SnWebFeedConfigCopyWith<$Res>(_self.config, (value) {
|
||||||
return _then(_self.copyWith(config: value));
|
return _then(_self.copyWith(config: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -243,19 +243,19 @@ $WebFeedConfigCopyWith<$Res> get config {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _WebFeed implements WebFeed {
|
class _SnWebFeed implements SnWebFeed {
|
||||||
const _WebFeed({required this.id, required this.url, required this.title, this.description, this.preview, this.config = const WebFeedConfig(), required this.publisherId, final List<WebArticle> articles = const [], required this.createdAt, required this.updatedAt, this.deletedAt}): _articles = articles;
|
const _SnWebFeed({required this.id, required this.url, required this.title, this.description, this.preview, this.config = const SnWebFeedConfig(), required this.publisherId, final List<SnWebArticle> articles = const [], required this.createdAt, required this.updatedAt, this.deletedAt}): _articles = articles;
|
||||||
factory _WebFeed.fromJson(Map<String, dynamic> json) => _$WebFeedFromJson(json);
|
factory _SnWebFeed.fromJson(Map<String, dynamic> json) => _$SnWebFeedFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@override final String url;
|
@override final String url;
|
||||||
@override final String title;
|
@override final String title;
|
||||||
@override final String? description;
|
@override final String? description;
|
||||||
@override final SnScrappedLink? preview;
|
@override final SnScrappedLink? preview;
|
||||||
@override@JsonKey() final WebFeedConfig config;
|
@override@JsonKey() final SnWebFeedConfig config;
|
||||||
@override final String publisherId;
|
@override final String publisherId;
|
||||||
final List<WebArticle> _articles;
|
final List<SnWebArticle> _articles;
|
||||||
@override@JsonKey() List<WebArticle> get articles {
|
@override@JsonKey() List<SnWebArticle> get articles {
|
||||||
if (_articles is EqualUnmodifiableListView) return _articles;
|
if (_articles is EqualUnmodifiableListView) return _articles;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_articles);
|
return EqualUnmodifiableListView(_articles);
|
||||||
@ -265,20 +265,20 @@ class _WebFeed implements WebFeed {
|
|||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
|
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$WebFeedCopyWith<_WebFeed> get copyWith => __$WebFeedCopyWithImpl<_WebFeed>(this, _$identity);
|
_$SnWebFeedCopyWith<_SnWebFeed> get copyWith => __$SnWebFeedCopyWithImpl<_SnWebFeed>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$WebFeedToJson(this, );
|
return _$SnWebFeedToJson(this, );
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebFeed&&(identical(other.id, id) || other.id == id)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.config, config) || other.config == config)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&const DeepCollectionEquality().equals(other._articles, _articles)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnWebFeed&&(identical(other.id, id) || other.id == id)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.config, config) || other.config == config)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&const DeepCollectionEquality().equals(other._articles, _articles)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -287,52 +287,52 @@ int get hashCode => Object.hash(runtimeType,id,url,title,description,preview,con
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebFeed(id: $id, url: $url, title: $title, description: $description, preview: $preview, config: $config, publisherId: $publisherId, articles: $articles, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWebFeed(id: $id, url: $url, title: $title, description: $description, preview: $preview, config: $config, publisherId: $publisherId, articles: $articles, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class _$WebFeedCopyWith<$Res> implements $WebFeedCopyWith<$Res> {
|
abstract mixin class _$SnWebFeedCopyWith<$Res> implements $SnWebFeedCopyWith<$Res> {
|
||||||
factory _$WebFeedCopyWith(_WebFeed value, $Res Function(_WebFeed) _then) = __$WebFeedCopyWithImpl;
|
factory _$SnWebFeedCopyWith(_SnWebFeed value, $Res Function(_SnWebFeed) _then) = __$SnWebFeedCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String url, String title, String? description, SnScrappedLink? preview, WebFeedConfig config, String publisherId, List<WebArticle> articles, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String url, String title, String? description, SnScrappedLink? preview, SnWebFeedConfig config, String publisherId, List<SnWebArticle> articles, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $SnScrappedLinkCopyWith<$Res>? get preview;@override $WebFeedConfigCopyWith<$Res> get config;
|
@override $SnScrappedLinkCopyWith<$Res>? get preview;@override $SnWebFeedConfigCopyWith<$Res> get config;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$WebFeedCopyWithImpl<$Res>
|
class __$SnWebFeedCopyWithImpl<$Res>
|
||||||
implements _$WebFeedCopyWith<$Res> {
|
implements _$SnWebFeedCopyWith<$Res> {
|
||||||
__$WebFeedCopyWithImpl(this._self, this._then);
|
__$SnWebFeedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final _WebFeed _self;
|
final _SnWebFeed _self;
|
||||||
final $Res Function(_WebFeed) _then;
|
final $Res Function(_SnWebFeed) _then;
|
||||||
|
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? url = null,Object? title = null,Object? description = freezed,Object? preview = freezed,Object? config = null,Object? publisherId = null,Object? articles = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? url = null,Object? title = null,Object? description = freezed,Object? preview = freezed,Object? config = null,Object? publisherId = null,Object? articles = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_WebFeed(
|
return _then(_SnWebFeed(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
|
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
as String?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
as SnScrappedLink?,config: null == config ? _self.config : config // ignore: cast_nullable_to_non_nullable
|
as SnScrappedLink?,config: null == config ? _self.config : config // ignore: cast_nullable_to_non_nullable
|
||||||
as WebFeedConfig,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
as SnWebFeedConfig,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,articles: null == articles ? _self._articles : articles // ignore: cast_nullable_to_non_nullable
|
as String,articles: null == articles ? _self._articles : articles // ignore: cast_nullable_to_non_nullable
|
||||||
as List<WebArticle>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as List<SnWebArticle>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of WebFeed
|
/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@ -344,13 +344,13 @@ $SnScrappedLinkCopyWith<$Res>? get preview {
|
|||||||
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
||||||
return _then(_self.copyWith(preview: value));
|
return _then(_self.copyWith(preview: value));
|
||||||
});
|
});
|
||||||
}/// Create a copy of WebFeed
|
}/// Create a copy of SnWebFeed
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$WebFeedConfigCopyWith<$Res> get config {
|
$SnWebFeedConfigCopyWith<$Res> get config {
|
||||||
|
|
||||||
return $WebFeedConfigCopyWith<$Res>(_self.config, (value) {
|
return $SnWebFeedConfigCopyWith<$Res>(_self.config, (value) {
|
||||||
return _then(_self.copyWith(config: value));
|
return _then(_self.copyWith(config: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -358,59 +358,59 @@ $WebFeedConfigCopyWith<$Res> get config {
|
|||||||
|
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$WebArticle {
|
mixin _$SnWebArticle {
|
||||||
|
|
||||||
String get id; String get title; String get url; String? get author; Map<String, dynamic>? get meta; SnScrappedLink? get preview; String? get content; DateTime? get publishedAt; String get feedId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String get title; String get url; String? get author; Map<String, dynamic>? get meta; SnScrappedLink? get preview; SnWebFeed? get feed; String? get content; DateTime? get publishedAt; String get feedId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$WebArticleCopyWith<WebArticle> get copyWith => _$WebArticleCopyWithImpl<WebArticle>(this as WebArticle, _$identity);
|
$SnWebArticleCopyWith<SnWebArticle> get copyWith => _$SnWebArticleCopyWithImpl<SnWebArticle>(this as SnWebArticle, _$identity);
|
||||||
|
|
||||||
/// Serializes this WebArticle to a JSON map.
|
/// Serializes this SnWebArticle to a JSON map.
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebArticle&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.url, url) || other.url == url)&&(identical(other.author, author) || other.author == author)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.content, content) || other.content == content)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnWebArticle&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.url, url) || other.url == url)&&(identical(other.author, author) || other.author == author)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.feed, feed) || other.feed == feed)&&(identical(other.content, content) || other.content == content)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,title,url,author,const DeepCollectionEquality().hash(meta),preview,content,publishedAt,feedId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,title,url,author,const DeepCollectionEquality().hash(meta),preview,feed,content,publishedAt,feedId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebArticle(id: $id, title: $title, url: $url, author: $author, meta: $meta, preview: $preview, content: $content, publishedAt: $publishedAt, feedId: $feedId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWebArticle(id: $id, title: $title, url: $url, author: $author, meta: $meta, preview: $preview, feed: $feed, content: $content, publishedAt: $publishedAt, feedId: $feedId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class $WebArticleCopyWith<$Res> {
|
abstract mixin class $SnWebArticleCopyWith<$Res> {
|
||||||
factory $WebArticleCopyWith(WebArticle value, $Res Function(WebArticle) _then) = _$WebArticleCopyWithImpl;
|
factory $SnWebArticleCopyWith(SnWebArticle value, $Res Function(SnWebArticle) _then) = _$SnWebArticleCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String title, String url, String? author, Map<String, dynamic>? meta, SnScrappedLink? preview, String? content, DateTime? publishedAt, String feedId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String title, String url, String? author, Map<String, dynamic>? meta, SnScrappedLink? preview, SnWebFeed? feed, String? content, DateTime? publishedAt, String feedId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$SnScrappedLinkCopyWith<$Res>? get preview;
|
$SnScrappedLinkCopyWith<$Res>? get preview;$SnWebFeedCopyWith<$Res>? get feed;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$WebArticleCopyWithImpl<$Res>
|
class _$SnWebArticleCopyWithImpl<$Res>
|
||||||
implements $WebArticleCopyWith<$Res> {
|
implements $SnWebArticleCopyWith<$Res> {
|
||||||
_$WebArticleCopyWithImpl(this._self, this._then);
|
_$SnWebArticleCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final WebArticle _self;
|
final SnWebArticle _self;
|
||||||
final $Res Function(WebArticle) _then;
|
final $Res Function(SnWebArticle) _then;
|
||||||
|
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = null,Object? url = null,Object? author = freezed,Object? meta = freezed,Object? preview = freezed,Object? content = freezed,Object? publishedAt = freezed,Object? feedId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = null,Object? url = null,Object? author = freezed,Object? meta = freezed,Object? preview = freezed,Object? feed = freezed,Object? content = freezed,Object? publishedAt = freezed,Object? feedId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
@ -418,7 +418,8 @@ as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nul
|
|||||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
as String?,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
as SnScrappedLink?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
as SnScrappedLink?,feed: freezed == feed ? _self.feed : feed // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnWebFeed?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
|
as String?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,feedId: null == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
as DateTime?,feedId: null == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -427,7 +428,7 @@ as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ign
|
|||||||
as DateTime?,
|
as DateTime?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@ -439,6 +440,18 @@ $SnScrappedLinkCopyWith<$Res>? get preview {
|
|||||||
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
||||||
return _then(_self.copyWith(preview: value));
|
return _then(_self.copyWith(preview: value));
|
||||||
});
|
});
|
||||||
|
}/// Create a copy of SnWebArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnWebFeedCopyWith<$Res>? get feed {
|
||||||
|
if (_self.feed == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnWebFeedCopyWith<$Res>(_self.feed!, (value) {
|
||||||
|
return _then(_self.copyWith(feed: value));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,9 +459,9 @@ $SnScrappedLinkCopyWith<$Res>? get preview {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _WebArticle implements WebArticle {
|
class _SnWebArticle implements SnWebArticle {
|
||||||
const _WebArticle({required this.id, required this.title, required this.url, this.author, final Map<String, dynamic>? meta, this.preview, this.content, this.publishedAt, required this.feedId, required this.createdAt, required this.updatedAt, this.deletedAt}): _meta = meta;
|
const _SnWebArticle({required this.id, required this.title, required this.url, this.author, final Map<String, dynamic>? meta, this.preview, this.feed, this.content, this.publishedAt, required this.feedId, required this.createdAt, required this.updatedAt, this.deletedAt}): _meta = meta;
|
||||||
factory _WebArticle.fromJson(Map<String, dynamic> json) => _$WebArticleFromJson(json);
|
factory _SnWebArticle.fromJson(Map<String, dynamic> json) => _$SnWebArticleFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@override final String title;
|
@override final String title;
|
||||||
@ -464,6 +477,7 @@ class _WebArticle implements WebArticle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override final SnScrappedLink? preview;
|
@override final SnScrappedLink? preview;
|
||||||
|
@override final SnWebFeed? feed;
|
||||||
@override final String? content;
|
@override final String? content;
|
||||||
@override final DateTime? publishedAt;
|
@override final DateTime? publishedAt;
|
||||||
@override final String feedId;
|
@override final String feedId;
|
||||||
@ -471,65 +485,66 @@ class _WebArticle implements WebArticle {
|
|||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
|
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$WebArticleCopyWith<_WebArticle> get copyWith => __$WebArticleCopyWithImpl<_WebArticle>(this, _$identity);
|
_$SnWebArticleCopyWith<_SnWebArticle> get copyWith => __$SnWebArticleCopyWithImpl<_SnWebArticle>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$WebArticleToJson(this, );
|
return _$SnWebArticleToJson(this, );
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebArticle&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.url, url) || other.url == url)&&(identical(other.author, author) || other.author == author)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.content, content) || other.content == content)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnWebArticle&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.url, url) || other.url == url)&&(identical(other.author, author) || other.author == author)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.feed, feed) || other.feed == feed)&&(identical(other.content, content) || other.content == content)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,title,url,author,const DeepCollectionEquality().hash(_meta),preview,content,publishedAt,feedId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,title,url,author,const DeepCollectionEquality().hash(_meta),preview,feed,content,publishedAt,feedId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'WebArticle(id: $id, title: $title, url: $url, author: $author, meta: $meta, preview: $preview, content: $content, publishedAt: $publishedAt, feedId: $feedId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWebArticle(id: $id, title: $title, url: $url, author: $author, meta: $meta, preview: $preview, feed: $feed, content: $content, publishedAt: $publishedAt, feedId: $feedId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class _$WebArticleCopyWith<$Res> implements $WebArticleCopyWith<$Res> {
|
abstract mixin class _$SnWebArticleCopyWith<$Res> implements $SnWebArticleCopyWith<$Res> {
|
||||||
factory _$WebArticleCopyWith(_WebArticle value, $Res Function(_WebArticle) _then) = __$WebArticleCopyWithImpl;
|
factory _$SnWebArticleCopyWith(_SnWebArticle value, $Res Function(_SnWebArticle) _then) = __$SnWebArticleCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String title, String url, String? author, Map<String, dynamic>? meta, SnScrappedLink? preview, String? content, DateTime? publishedAt, String feedId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String title, String url, String? author, Map<String, dynamic>? meta, SnScrappedLink? preview, SnWebFeed? feed, String? content, DateTime? publishedAt, String feedId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $SnScrappedLinkCopyWith<$Res>? get preview;
|
@override $SnScrappedLinkCopyWith<$Res>? get preview;@override $SnWebFeedCopyWith<$Res>? get feed;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$WebArticleCopyWithImpl<$Res>
|
class __$SnWebArticleCopyWithImpl<$Res>
|
||||||
implements _$WebArticleCopyWith<$Res> {
|
implements _$SnWebArticleCopyWith<$Res> {
|
||||||
__$WebArticleCopyWithImpl(this._self, this._then);
|
__$SnWebArticleCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final _WebArticle _self;
|
final _SnWebArticle _self;
|
||||||
final $Res Function(_WebArticle) _then;
|
final $Res Function(_SnWebArticle) _then;
|
||||||
|
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = null,Object? url = null,Object? author = freezed,Object? meta = freezed,Object? preview = freezed,Object? content = freezed,Object? publishedAt = freezed,Object? feedId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = null,Object? url = null,Object? author = freezed,Object? meta = freezed,Object? preview = freezed,Object? feed = freezed,Object? content = freezed,Object? publishedAt = freezed,Object? feedId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_WebArticle(
|
return _then(_SnWebArticle(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
|
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
|
||||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
as String?,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
as SnScrappedLink?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
as SnScrappedLink?,feed: freezed == feed ? _self.feed : feed // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnWebFeed?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
|
as String?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,feedId: null == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
as DateTime?,feedId: null == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -539,7 +554,7 @@ as DateTime?,
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of WebArticle
|
/// Create a copy of SnWebArticle
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@ -551,6 +566,18 @@ $SnScrappedLinkCopyWith<$Res>? get preview {
|
|||||||
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
return $SnScrappedLinkCopyWith<$Res>(_self.preview!, (value) {
|
||||||
return _then(_self.copyWith(preview: value));
|
return _then(_self.copyWith(preview: value));
|
||||||
});
|
});
|
||||||
|
}/// Create a copy of SnWebArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnWebFeedCopyWith<$Res>? get feed {
|
||||||
|
if (_self.feed == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnWebFeedCopyWith<$Res>(_self.feed!, (value) {
|
||||||
|
return _then(_self.copyWith(feed: value));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,13 +6,13 @@ part of 'webfeed.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
_WebFeedConfig _$WebFeedConfigFromJson(Map<String, dynamic> json) =>
|
_SnWebFeedConfig _$SnWebFeedConfigFromJson(Map<String, dynamic> json) =>
|
||||||
_WebFeedConfig(scrapPage: json['scrap_page'] as bool? ?? false);
|
_SnWebFeedConfig(scrapPage: json['scrap_page'] as bool? ?? false);
|
||||||
|
|
||||||
Map<String, dynamic> _$WebFeedConfigToJson(_WebFeedConfig instance) =>
|
Map<String, dynamic> _$SnWebFeedConfigToJson(_SnWebFeedConfig instance) =>
|
||||||
<String, dynamic>{'scrap_page': instance.scrapPage};
|
<String, dynamic>{'scrap_page': instance.scrapPage};
|
||||||
|
|
||||||
_WebFeed _$WebFeedFromJson(Map<String, dynamic> json) => _WebFeed(
|
_SnWebFeed _$SnWebFeedFromJson(Map<String, dynamic> json) => _SnWebFeed(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
url: json['url'] as String,
|
url: json['url'] as String,
|
||||||
title: json['title'] as String,
|
title: json['title'] as String,
|
||||||
@ -23,12 +23,12 @@ _WebFeed _$WebFeedFromJson(Map<String, dynamic> json) => _WebFeed(
|
|||||||
: SnScrappedLink.fromJson(json['preview'] as Map<String, dynamic>),
|
: SnScrappedLink.fromJson(json['preview'] as Map<String, dynamic>),
|
||||||
config:
|
config:
|
||||||
json['config'] == null
|
json['config'] == null
|
||||||
? const WebFeedConfig()
|
? const SnWebFeedConfig()
|
||||||
: WebFeedConfig.fromJson(json['config'] as Map<String, dynamic>),
|
: SnWebFeedConfig.fromJson(json['config'] as Map<String, dynamic>),
|
||||||
publisherId: json['publisher_id'] as String,
|
publisherId: json['publisher_id'] as String,
|
||||||
articles:
|
articles:
|
||||||
(json['articles'] as List<dynamic>?)
|
(json['articles'] as List<dynamic>?)
|
||||||
?.map((e) => WebArticle.fromJson(e as Map<String, dynamic>))
|
?.map((e) => SnWebArticle.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [],
|
const [],
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
@ -39,45 +39,53 @@ _WebFeed _$WebFeedFromJson(Map<String, dynamic> json) => _WebFeed(
|
|||||||
: DateTime.parse(json['deleted_at'] as String),
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$WebFeedToJson(_WebFeed instance) => <String, dynamic>{
|
Map<String, dynamic> _$SnWebFeedToJson(_SnWebFeed instance) =>
|
||||||
'id': instance.id,
|
<String, dynamic>{
|
||||||
'url': instance.url,
|
'id': instance.id,
|
||||||
'title': instance.title,
|
'url': instance.url,
|
||||||
'description': instance.description,
|
'title': instance.title,
|
||||||
'preview': instance.preview?.toJson(),
|
'description': instance.description,
|
||||||
'config': instance.config.toJson(),
|
'preview': instance.preview?.toJson(),
|
||||||
'publisher_id': instance.publisherId,
|
'config': instance.config.toJson(),
|
||||||
'articles': instance.articles.map((e) => e.toJson()).toList(),
|
'publisher_id': instance.publisherId,
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'articles': instance.articles.map((e) => e.toJson()).toList(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
};
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
};
|
||||||
|
|
||||||
_WebArticle _$WebArticleFromJson(Map<String, dynamic> json) => _WebArticle(
|
_SnWebArticle _$SnWebArticleFromJson(Map<String, dynamic> json) =>
|
||||||
id: json['id'] as String,
|
_SnWebArticle(
|
||||||
title: json['title'] as String,
|
id: json['id'] as String,
|
||||||
url: json['url'] as String,
|
title: json['title'] as String,
|
||||||
author: json['author'] as String?,
|
url: json['url'] as String,
|
||||||
meta: json['meta'] as Map<String, dynamic>?,
|
author: json['author'] as String?,
|
||||||
preview:
|
meta: json['meta'] as Map<String, dynamic>?,
|
||||||
json['preview'] == null
|
preview:
|
||||||
? null
|
json['preview'] == null
|
||||||
: SnScrappedLink.fromJson(json['preview'] as Map<String, dynamic>),
|
? null
|
||||||
content: json['content'] as String?,
|
: SnScrappedLink.fromJson(
|
||||||
publishedAt:
|
json['preview'] as Map<String, dynamic>,
|
||||||
json['published_at'] == null
|
),
|
||||||
? null
|
feed:
|
||||||
: DateTime.parse(json['published_at'] as String),
|
json['feed'] == null
|
||||||
feedId: json['feed_id'] as String,
|
? null
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
: SnWebFeed.fromJson(json['feed'] as Map<String, dynamic>),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
content: json['content'] as String?,
|
||||||
deletedAt:
|
publishedAt:
|
||||||
json['deleted_at'] == null
|
json['published_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
: DateTime.parse(json['published_at'] as String),
|
||||||
);
|
feedId: json['feed_id'] as String,
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt:
|
||||||
|
json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$WebArticleToJson(_WebArticle instance) =>
|
Map<String, dynamic> _$SnWebArticleToJson(_SnWebArticle instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'title': instance.title,
|
'title': instance.title,
|
||||||
@ -85,6 +93,7 @@ Map<String, dynamic> _$WebArticleToJson(_WebArticle instance) =>
|
|||||||
'author': instance.author,
|
'author': instance.author,
|
||||||
'meta': instance.meta,
|
'meta': instance.meta,
|
||||||
'preview': instance.preview?.toJson(),
|
'preview': instance.preview?.toJson(),
|
||||||
|
'feed': instance.feed?.toJson(),
|
||||||
'content': instance.content,
|
'content': instance.content,
|
||||||
'published_at': instance.publishedAt?.toIso8601String(),
|
'published_at': instance.publishedAt?.toIso8601String(),
|
||||||
'feed_id': instance.feedId,
|
'feed_id': instance.feedId,
|
||||||
|
31
lib/pods/article_detail.dart
Normal file
31
lib/pods/article_detail.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:island/models/webfeed.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
|
||||||
|
/// Provider that fetches a single article by its ID
|
||||||
|
final articleDetailProvider = FutureProvider.autoDispose.family<SnWebArticle, String>(
|
||||||
|
(ref, articleId) async {
|
||||||
|
final dio = ref.watch(apiClientProvider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await dio.get<Map<String, dynamic>>(
|
||||||
|
'/feeds/articles/$articleId',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200 && response.data != null) {
|
||||||
|
return SnWebArticle.fromJson(response.data!);
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load article');
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
if (e.response?.statusCode == 404) {
|
||||||
|
throw Exception('Article not found');
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load article: ${e.message}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Failed to load article: $e');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
1
lib/pods/article_list.dart
Normal file
1
lib/pods/article_list.dart
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -1,28 +1,31 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:island/models/webfeed.dart';
|
import 'package:island/models/webfeed.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
|
||||||
final webFeedListProvider = FutureProvider.family<List<WebFeed>, String>((
|
final webFeedListProvider = FutureProvider.family<List<SnWebFeed>, String>((
|
||||||
ref,
|
ref,
|
||||||
pubName,
|
pubName,
|
||||||
) async {
|
) async {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final response = await client.get('/publishers/$pubName/feeds');
|
final response = await client.get('/publishers/$pubName/feeds');
|
||||||
return (response.data as List).map((json) => WebFeed.fromJson(json)).toList();
|
return (response.data as List)
|
||||||
|
.map((json) => SnWebFeed.fromJson(json))
|
||||||
|
.toList();
|
||||||
});
|
});
|
||||||
|
|
||||||
class WebFeedNotifier
|
class WebFeedNotifier
|
||||||
extends
|
extends
|
||||||
AutoDisposeFamilyAsyncNotifier<
|
AutoDisposeFamilyAsyncNotifier<
|
||||||
WebFeed,
|
SnWebFeed,
|
||||||
({String pubName, String? feedId})
|
({String pubName, String? feedId})
|
||||||
> {
|
> {
|
||||||
@override
|
@override
|
||||||
FutureOr<WebFeed> build(({String pubName, String? feedId}) arg) async {
|
FutureOr<SnWebFeed> build(({String pubName, String? feedId}) arg) async {
|
||||||
if (arg.feedId == null || arg.feedId!.isEmpty) {
|
if (arg.feedId == null || arg.feedId!.isEmpty) {
|
||||||
return WebFeed(
|
return SnWebFeed(
|
||||||
id: '',
|
id: '',
|
||||||
url: '',
|
url: '',
|
||||||
title: '',
|
title: '',
|
||||||
@ -38,13 +41,13 @@ class WebFeedNotifier
|
|||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/publishers/${arg.pubName}/feeds/${arg.feedId}',
|
'/publishers/${arg.pubName}/feeds/${arg.feedId}',
|
||||||
);
|
);
|
||||||
return WebFeed.fromJson(response.data);
|
return SnWebFeed.fromJson(response.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveFeed(WebFeed feed) async {
|
Future<void> saveFeed(SnWebFeed feed) async {
|
||||||
state = const AsyncValue.loading();
|
state = const AsyncValue.loading();
|
||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
@ -55,7 +58,7 @@ class WebFeedNotifier
|
|||||||
? await client.post(url, data: feed.toJson())
|
? await client.post(url, data: feed.toJson())
|
||||||
: await client.patch('$url/${feed.id}', data: feed.toJson());
|
: await client.patch('$url/${feed.id}', data: feed.toJson());
|
||||||
|
|
||||||
state = AsyncValue.data(WebFeed.fromJson(response.data));
|
state = AsyncValue.data(SnWebFeed.fromJson(response.data));
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
state = AsyncValue.error(error, stackTrace);
|
state = AsyncValue.error(error, stackTrace);
|
||||||
rethrow;
|
rethrow;
|
||||||
@ -71,7 +74,7 @@ class WebFeedNotifier
|
|||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.delete('/publishers/${arg.pubName}/feeds/$feedId');
|
await client.delete('/publishers/${arg.pubName}/feeds/$feedId');
|
||||||
state = AsyncValue.data(
|
state = AsyncValue.data(
|
||||||
WebFeed(
|
SnWebFeed(
|
||||||
id: '',
|
id: '',
|
||||||
url: '',
|
url: '',
|
||||||
title: '',
|
title: '',
|
||||||
@ -94,13 +97,19 @@ class WebFeedNotifier
|
|||||||
state = const AsyncValue.loading();
|
state = const AsyncValue.loading();
|
||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
await client.post('/publishers/${arg.pubName}/feeds/$feedId/scrap');
|
await client.post(
|
||||||
|
'/publishers/${arg.pubName}/feeds/$feedId/scrap',
|
||||||
|
options: Options(
|
||||||
|
sendTimeout: const Duration(seconds: 60),
|
||||||
|
receiveTimeout: const Duration(seconds: 180),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// Reload the feed
|
// Reload the feed
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/publishers/${arg.pubName}/feeds/$feedId',
|
'/publishers/${arg.pubName}/feeds/$feedId',
|
||||||
);
|
);
|
||||||
state = AsyncValue.data(WebFeed.fromJson(response.data));
|
state = AsyncValue.data(SnWebFeed.fromJson(response.data));
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
state = AsyncValue.error(error, stackTrace);
|
state = AsyncValue.error(error, stackTrace);
|
||||||
rethrow;
|
rethrow;
|
||||||
@ -109,6 +118,6 @@ class WebFeedNotifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
final webFeedNotifierProvider = AsyncNotifierProvider.autoDispose
|
final webFeedNotifierProvider = AsyncNotifierProvider.autoDispose
|
||||||
.family<WebFeedNotifier, WebFeed, ({String pubName, String? feedId})>(
|
.family<WebFeedNotifier, SnWebFeed, ({String pubName, String? feedId})>(
|
||||||
WebFeedNotifier.new,
|
WebFeedNotifier.new,
|
||||||
);
|
);
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/screens/about.dart';
|
||||||
import 'package:island/screens/developers/apps.dart';
|
import 'package:island/screens/developers/apps.dart';
|
||||||
import 'package:island/screens/developers/edit_app.dart';
|
import 'package:island/screens/developers/edit_app.dart';
|
||||||
import 'package:island/screens/developers/new_app.dart';
|
import 'package:island/screens/developers/new_app.dart';
|
||||||
import 'package:island/screens/developers/hub.dart';
|
import 'package:island/screens/developers/hub.dart';
|
||||||
|
import 'package:island/screens/discovery/articles.dart';
|
||||||
|
import 'package:island/screens/posts/post_search.dart';
|
||||||
import 'package:island/widgets/app_wrapper.dart';
|
import 'package:island/widgets/app_wrapper.dart';
|
||||||
import 'package:island/screens/tabs.dart';
|
import 'package:island/screens/tabs.dart';
|
||||||
|
|
||||||
import 'package:island/screens/explore.dart';
|
import 'package:island/screens/explore.dart';
|
||||||
|
import 'package:island/screens/article_detail_screen.dart';
|
||||||
import 'package:island/screens/account.dart';
|
import 'package:island/screens/account.dart';
|
||||||
import 'package:island/screens/notification.dart';
|
import 'package:island/screens/notification.dart';
|
||||||
import 'package:island/screens/wallet.dart';
|
import 'package:island/screens/wallet.dart';
|
||||||
@ -219,6 +222,19 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Web articles
|
||||||
|
GoRoute(
|
||||||
|
path: '/feeds/articles',
|
||||||
|
builder: (context, state) => const ArticlesScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/feeds/articles/:id',
|
||||||
|
builder: (context, state) {
|
||||||
|
final id = state.pathParameters['id']!;
|
||||||
|
return ArticleDetailScreen(articleId: id);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
// Auth routes
|
// Auth routes
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/auth/login',
|
path: '/auth/login',
|
||||||
@ -234,6 +250,10 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
path: '/settings',
|
path: '/settings',
|
||||||
builder: (context, state) => const SettingsScreen(),
|
builder: (context, state) => const SettingsScreen(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/about',
|
||||||
|
builder: (context, state) => const AboutScreen(),
|
||||||
|
),
|
||||||
|
|
||||||
// Main tabs with TabsScreen shell
|
// Main tabs with TabsScreen shell
|
||||||
ShellRoute(
|
ShellRoute(
|
||||||
@ -251,6 +271,10 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
path: '/',
|
path: '/',
|
||||||
builder: (context, state) => const ExploreScreen(),
|
builder: (context, state) => const ExploreScreen(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/posts/search',
|
||||||
|
builder: (context, state) => const PostSearchScreen(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/posts/:id',
|
path: '/posts/:id',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
300
lib/screens/about.dart
Normal file
300
lib/screens/about.dart
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class AboutScreen extends StatefulWidget {
|
||||||
|
const AboutScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AboutScreen> createState() => _AboutScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AboutScreenState extends State<AboutScreen> {
|
||||||
|
PackageInfo _packageInfo = PackageInfo(
|
||||||
|
appName: 'Island',
|
||||||
|
packageName: 'com.example.island',
|
||||||
|
version: '1.0.0',
|
||||||
|
buildNumber: '1',
|
||||||
|
);
|
||||||
|
bool _isLoading = true;
|
||||||
|
String? _errorMessage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_initPackageInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initPackageInfo() async {
|
||||||
|
try {
|
||||||
|
final info = await PackageInfo.fromPlatform();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_packageInfo = info;
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_errorMessage = 'Failed to load package info: $e';
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _launchURL(String url) async {
|
||||||
|
final uri = Uri.parse(url);
|
||||||
|
if (await canLaunchUrl(uri)) {
|
||||||
|
await launchUrl(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('About'), elevation: 0),
|
||||||
|
body:
|
||||||
|
_isLoading
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: _errorMessage != null
|
||||||
|
? Center(child: Text(_errorMessage!))
|
||||||
|
: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
// App Icon and Name
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 50,
|
||||||
|
backgroundColor: theme.colorScheme.primary.withOpacity(
|
||||||
|
0.1,
|
||||||
|
),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/icons/icon.png',
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
_packageInfo.appName,
|
||||||
|
style: theme.textTheme.headlineSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Version ${_packageInfo.version} (${_packageInfo.buildNumber})',
|
||||||
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: theme.textTheme.bodySmall?.color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
|
||||||
|
// App Info Card
|
||||||
|
_buildSection(
|
||||||
|
context,
|
||||||
|
title: 'App Information',
|
||||||
|
children: [
|
||||||
|
_buildInfoItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.info_outline,
|
||||||
|
label: 'Package Name',
|
||||||
|
value: _packageInfo.packageName,
|
||||||
|
),
|
||||||
|
_buildInfoItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.update,
|
||||||
|
label: 'Version',
|
||||||
|
value: _packageInfo.version,
|
||||||
|
),
|
||||||
|
_buildInfoItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.build,
|
||||||
|
label: 'Build Number',
|
||||||
|
value: _packageInfo.buildNumber,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Links Card
|
||||||
|
_buildSection(
|
||||||
|
context,
|
||||||
|
title: 'Links',
|
||||||
|
children: [
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Icons.privacy_tip_outlined,
|
||||||
|
title: 'Privacy Policy',
|
||||||
|
onTap:
|
||||||
|
() => _launchURL(
|
||||||
|
'https://solsynth.dev/terms/privacy-policy',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Icons.description_outlined,
|
||||||
|
title: 'Terms of Service',
|
||||||
|
onTap:
|
||||||
|
() => _launchURL(
|
||||||
|
'https://example.com/terms/basic-law',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Icons.code,
|
||||||
|
title: 'Open Source Licenses',
|
||||||
|
onTap: () {
|
||||||
|
showLicensePage(
|
||||||
|
context: context,
|
||||||
|
applicationName: _packageInfo.appName,
|
||||||
|
applicationVersion:
|
||||||
|
'Version ${_packageInfo.version}',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Developer Info
|
||||||
|
_buildSection(
|
||||||
|
context,
|
||||||
|
title: 'Developer',
|
||||||
|
children: [
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Icons.email_outlined,
|
||||||
|
title: 'Contact Us',
|
||||||
|
subtitle: 'lily@solsynth.dev',
|
||||||
|
onTap: () => _launchURL('mailto:lily@solsynth.dev'),
|
||||||
|
),
|
||||||
|
_buildListTile(
|
||||||
|
context,
|
||||||
|
icon: Icons.copyright,
|
||||||
|
title: 'License',
|
||||||
|
subtitle:
|
||||||
|
'Copyright reserved © ${DateTime.now().year} Solsynth\nGNU Affero General Public License v3.0',
|
||||||
|
onTap:
|
||||||
|
() => _launchURL(
|
||||||
|
'https://github.com/Solsynth/Solian/blob/v3/LICENSE.txt',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
|
||||||
|
// Copyright
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
'© ${DateTime.now().year} ${_packageInfo.appName}. All rights reserved.',
|
||||||
|
style: theme.textTheme.bodySmall,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSection(
|
||||||
|
BuildContext context, {
|
||||||
|
required String title,
|
||||||
|
required List<Widget> children,
|
||||||
|
}) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(height: 1),
|
||||||
|
...children,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoItem(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
}) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(icon, size: 20, color: Theme.of(context).hintColor),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(label, style: Theme.of(context).textTheme.bodySmall),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
SelectableText(
|
||||||
|
value,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (value.startsWith('http') || value.contains('@'))
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.copy, size: 16),
|
||||||
|
onPressed: () {
|
||||||
|
Clipboard.setData(ClipboardData(text: value));
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Copied to clipboard')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
tooltip: 'Copy to clipboard',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildListTile(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String title,
|
||||||
|
String? subtitle,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(icon),
|
||||||
|
title: Text(title),
|
||||||
|
subtitle: subtitle != null ? Text(subtitle) : null,
|
||||||
|
trailing: const Icon(Icons.chevron_right),
|
||||||
|
onTap: onTap,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
minLeadingWidth: 24,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -281,6 +281,16 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Divider(height: 1).padding(vertical: 8),
|
const Divider(height: 1).padding(vertical: 8),
|
||||||
|
ListTile(
|
||||||
|
minTileHeight: 48,
|
||||||
|
leading: const Icon(Symbols.info),
|
||||||
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
title: Text('about').tr(),
|
||||||
|
onTap: () {
|
||||||
|
context.push('/about');
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
leading: const Icon(Symbols.logout),
|
leading: const Icon(Symbols.logout),
|
||||||
|
105
lib/screens/article_detail_screen.dart
Normal file
105
lib/screens/article_detail_screen.dart
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/widgets/content/markdown.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
import 'package:island/models/webfeed.dart';
|
||||||
|
import 'package:island/pods/article_detail.dart';
|
||||||
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/loading_indicator.dart';
|
||||||
|
import 'package:html2md/html2md.dart' as html2md;
|
||||||
|
|
||||||
|
class ArticleDetailScreen extends ConsumerWidget {
|
||||||
|
final String articleId;
|
||||||
|
|
||||||
|
const ArticleDetailScreen({super.key, required this.articleId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final articleAsync = ref.watch(articleDetailProvider(articleId));
|
||||||
|
|
||||||
|
return AppScaffold(
|
||||||
|
body: articleAsync.when(
|
||||||
|
data:
|
||||||
|
(article) => AppScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: const BackButton(),
|
||||||
|
title: Text(article.title),
|
||||||
|
),
|
||||||
|
body: _ArticleDetailContent(article: article),
|
||||||
|
),
|
||||||
|
loading: () => const Center(child: LoadingIndicator()),
|
||||||
|
error:
|
||||||
|
(error, stackTrace) =>
|
||||||
|
Center(child: Text('Failed to load article: $error')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ArticleDetailContent extends HookConsumerWidget {
|
||||||
|
final SnWebArticle article;
|
||||||
|
|
||||||
|
const _ArticleDetailContent({required this.article});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final markdownContent = useMemoized(
|
||||||
|
() => html2md.convert(article.content ?? ''),
|
||||||
|
[article],
|
||||||
|
);
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
if (article.preview?.imageUrl != null)
|
||||||
|
Image.network(
|
||||||
|
article.preview!.imageUrl!,
|
||||||
|
width: double.infinity,
|
||||||
|
height: 200,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
article.title,
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
if (article.feed?.title != null)
|
||||||
|
Text(
|
||||||
|
article.feed!.title,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(height: 32),
|
||||||
|
if (article.content != null)
|
||||||
|
...MarkdownTextContent.buildGenerator(
|
||||||
|
isDark: Theme.of(context).brightness == Brightness.dark,
|
||||||
|
).buildWidgets(markdownContent)
|
||||||
|
else if (article.preview?.description != null)
|
||||||
|
Text(article.preview!.description!),
|
||||||
|
const Gap(24),
|
||||||
|
FilledButton(
|
||||||
|
onPressed:
|
||||||
|
() => launchUrlString(
|
||||||
|
article.url,
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
),
|
||||||
|
child: const Text('Read Full Article'),
|
||||||
|
),
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -40,12 +40,12 @@ class WebFeedEditScreen extends HookConsumerWidget {
|
|||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final feed = WebFeed(
|
final feed = SnWebFeed(
|
||||||
id: feedId ?? '',
|
id: feedId ?? '',
|
||||||
title: titleController.text,
|
title: titleController.text,
|
||||||
url: urlController.text,
|
url: urlController.text,
|
||||||
description: descriptionController.text,
|
description: descriptionController.text,
|
||||||
config: WebFeedConfig(scrapPage: isScrapEnabled.value),
|
config: SnWebFeedConfig(scrapPage: isScrapEnabled.value),
|
||||||
publisherId: pubName,
|
publisherId: pubName,
|
||||||
createdAt: DateTime.now(),
|
createdAt: DateTime.now(),
|
||||||
updatedAt: DateTime.now(),
|
updatedAt: DateTime.now(),
|
||||||
|
142
lib/screens/discovery/articles.dart
Normal file
142
lib/screens/discovery/articles.dart
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/webfeed.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/web_article_card.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
|
|
||||||
|
part 'articles.g.dart';
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
class ArticlesListNotifier extends _$ArticlesListNotifier
|
||||||
|
with CursorPagingNotifierMixin<SnWebArticle> {
|
||||||
|
static const int _pageSize = 20;
|
||||||
|
|
||||||
|
Map<String, dynamic> _params = {};
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CursorPagingData<SnWebArticle>> build({
|
||||||
|
String? feedId,
|
||||||
|
String? publisherId,
|
||||||
|
}) async {
|
||||||
|
_params = {
|
||||||
|
if (feedId != null) 'feedId': feedId,
|
||||||
|
if (publisherId != null) 'publisherId': publisherId,
|
||||||
|
};
|
||||||
|
return fetch(cursor: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CursorPagingData<SnWebArticle>> fetch({
|
||||||
|
required String? cursor,
|
||||||
|
}) async {
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
final offset = cursor == null ? 0 : int.parse(cursor);
|
||||||
|
|
||||||
|
final queryParams = {'limit': _pageSize, 'offset': offset, ..._params};
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await client.get(
|
||||||
|
'/feeds/articles',
|
||||||
|
queryParameters: queryParams,
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<dynamic> data = response.data;
|
||||||
|
final articles =
|
||||||
|
data
|
||||||
|
.map(
|
||||||
|
(json) => SnWebArticle.fromJson(json as Map<String, dynamic>),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final total = int.tryParse(response.headers.value('X-Total') ?? '0') ?? 0;
|
||||||
|
final hasMore = offset + articles.length < total;
|
||||||
|
final nextCursor = hasMore ? (offset + articles.length).toString() : null;
|
||||||
|
|
||||||
|
return CursorPagingData(
|
||||||
|
items: articles,
|
||||||
|
hasMore: hasMore,
|
||||||
|
nextCursor: nextCursor,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Error fetching articles: $e');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SliverArticlesList extends ConsumerWidget {
|
||||||
|
final String? feedId;
|
||||||
|
final String? publisherId;
|
||||||
|
final Color? backgroundColor;
|
||||||
|
final EdgeInsets? padding;
|
||||||
|
final Function? onRefresh;
|
||||||
|
|
||||||
|
const SliverArticlesList({
|
||||||
|
super.key,
|
||||||
|
this.feedId,
|
||||||
|
this.publisherId,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.padding,
|
||||||
|
this.onRefresh,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return PagingHelperSliverView(
|
||||||
|
provider: articlesListNotifierProvider(
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
),
|
||||||
|
futureRefreshable:
|
||||||
|
articlesListNotifierProvider(
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
).future,
|
||||||
|
notifierRefreshable:
|
||||||
|
articlesListNotifierProvider(
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
).notifier,
|
||||||
|
contentBuilder:
|
||||||
|
(data, widgetCount, endItemView) => SliverList.builder(
|
||||||
|
itemCount: widgetCount,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == widgetCount - 1) {
|
||||||
|
return endItemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
final article = data.items[index];
|
||||||
|
return WebArticleCard(article: article, showDetails: true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArticlesScreen extends ConsumerWidget {
|
||||||
|
final String? feedId;
|
||||||
|
final String? publisherId;
|
||||||
|
final String? title;
|
||||||
|
|
||||||
|
const ArticlesScreen({super.key, this.feedId, this.publisherId, this.title});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: Text(title ?? 'Articles')),
|
||||||
|
body: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.only(top: 8, left: 8, right: 8),
|
||||||
|
sliver: SliverArticlesList(
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
206
lib/screens/discovery/articles.g.dart
Normal file
206
lib/screens/discovery/articles.g.dart
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'articles.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$articlesListNotifierHash() =>
|
||||||
|
r'924f2344c3bbf0ff7b92fe69e88d3b64a534b538';
|
||||||
|
|
||||||
|
/// Copied from Dart SDK
|
||||||
|
class _SystemHash {
|
||||||
|
_SystemHash._();
|
||||||
|
|
||||||
|
static int combine(int hash, int value) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + value);
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||||
|
return hash ^ (hash >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finish(int hash) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = hash ^ (hash >> 11);
|
||||||
|
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _$ArticlesListNotifier
|
||||||
|
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnWebArticle>> {
|
||||||
|
late final String? feedId;
|
||||||
|
late final String? publisherId;
|
||||||
|
|
||||||
|
FutureOr<CursorPagingData<SnWebArticle>> build({
|
||||||
|
String? feedId,
|
||||||
|
String? publisherId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
@ProviderFor(ArticlesListNotifier)
|
||||||
|
const articlesListNotifierProvider = ArticlesListNotifierFamily();
|
||||||
|
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
class ArticlesListNotifierFamily
|
||||||
|
extends Family<AsyncValue<CursorPagingData<SnWebArticle>>> {
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
const ArticlesListNotifierFamily();
|
||||||
|
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
ArticlesListNotifierProvider call({String? feedId, String? publisherId}) {
|
||||||
|
return ArticlesListNotifierProvider(
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ArticlesListNotifierProvider getProviderOverride(
|
||||||
|
covariant ArticlesListNotifierProvider provider,
|
||||||
|
) {
|
||||||
|
return call(feedId: provider.feedId, publisherId: provider.publisherId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||||
|
_allTransitiveDependencies;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get name => r'articlesListNotifierProvider';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
class ArticlesListNotifierProvider
|
||||||
|
extends
|
||||||
|
AutoDisposeAsyncNotifierProviderImpl<
|
||||||
|
ArticlesListNotifier,
|
||||||
|
CursorPagingData<SnWebArticle>
|
||||||
|
> {
|
||||||
|
/// See also [ArticlesListNotifier].
|
||||||
|
ArticlesListNotifierProvider({String? feedId, String? publisherId})
|
||||||
|
: this._internal(
|
||||||
|
() =>
|
||||||
|
ArticlesListNotifier()
|
||||||
|
..feedId = feedId
|
||||||
|
..publisherId = publisherId,
|
||||||
|
from: articlesListNotifierProvider,
|
||||||
|
name: r'articlesListNotifierProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$articlesListNotifierHash,
|
||||||
|
dependencies: ArticlesListNotifierFamily._dependencies,
|
||||||
|
allTransitiveDependencies:
|
||||||
|
ArticlesListNotifierFamily._allTransitiveDependencies,
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
);
|
||||||
|
|
||||||
|
ArticlesListNotifierProvider._internal(
|
||||||
|
super._createNotifier, {
|
||||||
|
required super.name,
|
||||||
|
required super.dependencies,
|
||||||
|
required super.allTransitiveDependencies,
|
||||||
|
required super.debugGetCreateSourceHash,
|
||||||
|
required super.from,
|
||||||
|
required this.feedId,
|
||||||
|
required this.publisherId,
|
||||||
|
}) : super.internal();
|
||||||
|
|
||||||
|
final String? feedId;
|
||||||
|
final String? publisherId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<CursorPagingData<SnWebArticle>> runNotifierBuild(
|
||||||
|
covariant ArticlesListNotifier notifier,
|
||||||
|
) {
|
||||||
|
return notifier.build(feedId: feedId, publisherId: publisherId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Override overrideWith(ArticlesListNotifier Function() create) {
|
||||||
|
return ProviderOverride(
|
||||||
|
origin: this,
|
||||||
|
override: ArticlesListNotifierProvider._internal(
|
||||||
|
() =>
|
||||||
|
create()
|
||||||
|
..feedId = feedId
|
||||||
|
..publisherId = publisherId,
|
||||||
|
from: from,
|
||||||
|
name: null,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
debugGetCreateSourceHash: null,
|
||||||
|
feedId: feedId,
|
||||||
|
publisherId: publisherId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AutoDisposeAsyncNotifierProviderElement<
|
||||||
|
ArticlesListNotifier,
|
||||||
|
CursorPagingData<SnWebArticle>
|
||||||
|
>
|
||||||
|
createElement() {
|
||||||
|
return _ArticlesListNotifierProviderElement(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is ArticlesListNotifierProvider &&
|
||||||
|
other.feedId == feedId &&
|
||||||
|
other.publisherId == publisherId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, feedId.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, publisherId.hashCode);
|
||||||
|
|
||||||
|
return _SystemHash.finish(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
|
// ignore: unused_element
|
||||||
|
mixin ArticlesListNotifierRef
|
||||||
|
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnWebArticle>> {
|
||||||
|
/// The parameter `feedId` of this provider.
|
||||||
|
String? get feedId;
|
||||||
|
|
||||||
|
/// The parameter `publisherId` of this provider.
|
||||||
|
String? get publisherId;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ArticlesListNotifierProviderElement
|
||||||
|
extends
|
||||||
|
AutoDisposeAsyncNotifierProviderElement<
|
||||||
|
ArticlesListNotifier,
|
||||||
|
CursorPagingData<SnWebArticle>
|
||||||
|
>
|
||||||
|
with ArticlesListNotifierRef {
|
||||||
|
_ArticlesListNotifierProviderElement(super.provider);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get feedId => (origin as ArticlesListNotifierProvider).feedId;
|
||||||
|
@override
|
||||||
|
String? get publisherId =>
|
||||||
|
(origin as ArticlesListNotifierProvider).publisherId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:island/models/activity.dart';
|
import 'package:island/models/activity.dart';
|
||||||
import 'package:island/models/publisher.dart';
|
import 'package:island/models/publisher.dart';
|
||||||
import 'package:island/models/realm.dart';
|
import 'package:island/models/realm.dart';
|
||||||
|
import 'package:island/models/webfeed.dart';
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/services/responsive.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
@ -21,6 +22,7 @@ import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/widgets/realm/realm_card.dart';
|
import 'package:island/widgets/realm/realm_card.dart';
|
||||||
import 'package:island/widgets/publisher/publisher_card.dart';
|
import 'package:island/widgets/publisher/publisher_card.dart';
|
||||||
|
import 'package:island/widgets/web_article_card.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'explore.g.dart';
|
part 'explore.g.dart';
|
||||||
@ -91,37 +93,69 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
extendBody: false, // Prevent conflicts with tabs navigation
|
extendBody: false, // Prevent conflicts with tabs navigation
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
toolbarHeight: 0,
|
toolbarHeight: 0,
|
||||||
bottom: TabBar(
|
bottom: PreferredSize(
|
||||||
controller: tabController,
|
preferredSize: const Size.fromHeight(48),
|
||||||
tabs: [
|
child: Row(
|
||||||
Tab(
|
children: [
|
||||||
child: Text(
|
Expanded(
|
||||||
'explore'.tr(),
|
child: TabBar(
|
||||||
textAlign: TextAlign.center,
|
controller: tabController,
|
||||||
style: TextStyle(
|
tabAlignment: TabAlignment.start,
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
isScrollable: true,
|
||||||
|
tabs: [
|
||||||
|
Tab(
|
||||||
|
icon: Tooltip(
|
||||||
|
message: 'explore'.tr(),
|
||||||
|
child: Icon(
|
||||||
|
Symbols.explore,
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
icon: Tooltip(
|
||||||
|
message: 'exploreFilterSubscriptions'.tr(),
|
||||||
|
child: Icon(
|
||||||
|
Symbols.subscriptions,
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
icon: Tooltip(
|
||||||
|
message: 'exploreFilterFriends'.tr(),
|
||||||
|
child: Icon(
|
||||||
|
Symbols.people,
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Spacer(),
|
||||||
Tab(
|
IconButton(
|
||||||
child: Text(
|
onPressed: () {
|
||||||
'exploreFilterSubscriptions'.tr(),
|
context.push('/feeds/articles');
|
||||||
textAlign: TextAlign.center,
|
},
|
||||||
style: TextStyle(
|
icon: Icon(
|
||||||
|
Symbols.auto_stories,
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
),
|
),
|
||||||
|
tooltip: 'webArticlesStand'.tr(),
|
||||||
),
|
),
|
||||||
),
|
IconButton(
|
||||||
Tab(
|
onPressed: () {
|
||||||
child: Text(
|
context.push('/posts/search');
|
||||||
'exploreFilterFriends'.tr(),
|
},
|
||||||
textAlign: TextAlign.center,
|
icon: Icon(
|
||||||
style: TextStyle(
|
Symbols.search,
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
),
|
),
|
||||||
|
tooltip: 'search'.tr(),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
).padding(horizontal: 8),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
@ -196,6 +230,7 @@ class _DiscoveryActivityItem extends StatelessWidget {
|
|||||||
(switch (type) {
|
(switch (type) {
|
||||||
'realm' => 'discoverRealms',
|
'realm' => 'discoverRealms',
|
||||||
'publisher' => 'discoverPublishers',
|
'publisher' => 'discoverPublishers',
|
||||||
|
'article' => 'discoverWebArticles',
|
||||||
_ => 'unknown',
|
_ => 'unknown',
|
||||||
}).tr(),
|
}).tr(),
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
@ -221,6 +256,11 @@ class _DiscoveryActivityItem extends StatelessWidget {
|
|||||||
publisher: SnPublisher.fromJson(item['data']),
|
publisher: SnPublisher.fromJson(item['data']),
|
||||||
maxWidth: 280,
|
maxWidth: 280,
|
||||||
);
|
);
|
||||||
|
case 'article':
|
||||||
|
return WebArticleCard(
|
||||||
|
article: SnWebArticle.fromJson(item['data']),
|
||||||
|
maxWidth: 280,
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return Placeholder();
|
return Placeholder();
|
||||||
}
|
}
|
||||||
@ -342,7 +382,7 @@ class ActivityListNotifier extends _$ActivityListNotifier
|
|||||||
if (cursor != null) 'cursor': cursor,
|
if (cursor != null) 'cursor': cursor,
|
||||||
'take': take,
|
'take': take,
|
||||||
if (filter != null) 'filter': filter,
|
if (filter != null) 'filter': filter,
|
||||||
if (kDebugMode) 'debugInclude': 'realms,publishers',
|
if (kDebugMode) 'debugInclude': 'realms,publishers,articles',
|
||||||
};
|
};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
|
@ -7,7 +7,7 @@ part of 'explore.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$activityListNotifierHash() =>
|
String _$activityListNotifierHash() =>
|
||||||
r'57e9dcec944a9f88f8508b69fc91342592f5b349';
|
r'98b62fb9b958023d2c9e320af7ec1f1244836f49';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
165
lib/screens/posts/post_search.dart
Normal file
165
lib/screens/posts/post_search.dart
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/post.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/post/post_item.dart';
|
||||||
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
|
|
||||||
|
final postSearchNotifierProvider = StateNotifierProvider.autoDispose<
|
||||||
|
PostSearchNotifier,
|
||||||
|
AsyncValue<CursorPagingData<SnPost>>
|
||||||
|
>((ref) => PostSearchNotifier(ref));
|
||||||
|
|
||||||
|
class PostSearchNotifier
|
||||||
|
extends StateNotifier<AsyncValue<CursorPagingData<SnPost>>> {
|
||||||
|
final AutoDisposeRef ref;
|
||||||
|
static const int _pageSize = 20;
|
||||||
|
String _currentQuery = '';
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
PostSearchNotifier(this.ref) : super(const AsyncValue.loading()) {
|
||||||
|
state = const AsyncValue.data(
|
||||||
|
CursorPagingData(items: [], hasMore: false, nextCursor: null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> search(String query) async {
|
||||||
|
if (_isLoading) return;
|
||||||
|
|
||||||
|
_currentQuery = query.trim();
|
||||||
|
if (_currentQuery.isEmpty) {
|
||||||
|
state = AsyncValue.data(
|
||||||
|
CursorPagingData(items: [], hasMore: false, nextCursor: null),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetch(cursor: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetch({String? cursor}) async {
|
||||||
|
if (_isLoading) return;
|
||||||
|
|
||||||
|
_isLoading = true;
|
||||||
|
state = const AsyncValue.loading();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
final offset = cursor == null ? 0 : int.parse(cursor);
|
||||||
|
|
||||||
|
final response = await client.get(
|
||||||
|
'/posts/search',
|
||||||
|
queryParameters: {
|
||||||
|
'query': _currentQuery,
|
||||||
|
'offset': offset,
|
||||||
|
'take': _pageSize,
|
||||||
|
'useVector': true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final data = response.data as List;
|
||||||
|
final posts = data.map((json) => SnPost.fromJson(json)).toList();
|
||||||
|
final hasMore = posts.length == _pageSize;
|
||||||
|
final nextCursor = hasMore ? (offset + posts.length).toString() : null;
|
||||||
|
|
||||||
|
state = AsyncValue.data(
|
||||||
|
CursorPagingData(
|
||||||
|
items: posts,
|
||||||
|
hasMore: hasMore,
|
||||||
|
nextCursor: nextCursor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e, stack) {
|
||||||
|
state = AsyncValue.error(e, stack);
|
||||||
|
} finally {
|
||||||
|
_isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostSearchScreen extends ConsumerStatefulWidget {
|
||||||
|
const PostSearchScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<PostSearchScreen> createState() => _PostSearchScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PostSearchScreenState extends ConsumerState<PostSearchScreen> {
|
||||||
|
final _searchController = TextEditingController();
|
||||||
|
final _debounce = Duration(milliseconds: 500);
|
||||||
|
Timer? _debounceTimer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.dispose();
|
||||||
|
_debounceTimer?.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSearchChanged(String query) {
|
||||||
|
if (_debounceTimer?.isActive ?? false) _debounceTimer!.cancel();
|
||||||
|
|
||||||
|
_debounceTimer = Timer(_debounce, () {
|
||||||
|
ref.read(postSearchNotifierProvider.notifier).search(query);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: TextField(
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Search posts...',
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor,
|
||||||
|
),
|
||||||
|
onChanged: _onSearchChanged,
|
||||||
|
onSubmitted: (value) {
|
||||||
|
ref.read(postSearchNotifierProvider.notifier).search(value);
|
||||||
|
},
|
||||||
|
autofocus: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Consumer(
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final searchState = ref.watch(postSearchNotifierProvider);
|
||||||
|
|
||||||
|
return searchState.when(
|
||||||
|
data: (data) {
|
||||||
|
if (data.items.isEmpty && _searchController.text.isNotEmpty) {
|
||||||
|
return const Center(child: Text('No results found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: data.items.length + (data.hasMore ? 1 : 0),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index >= data.items.length) {
|
||||||
|
ref
|
||||||
|
.read(postSearchNotifierProvider.notifier)
|
||||||
|
.fetch(cursor: data.nextCursor);
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
|
||||||
|
final post = data.items[index];
|
||||||
|
return Column(
|
||||||
|
children: [PostItem(item: post), const Divider(height: 1)],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
lib/widgets/article/article_list.dart
Normal file
1
lib/widgets/article/article_list.dart
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -74,9 +74,7 @@ class MarkdownTextContent extends HookConsumerWidget {
|
|||||||
final url = Uri.tryParse(href);
|
final url = Uri.tryParse(href);
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
if (url.scheme == 'solian') {
|
if (url.scheme == 'solian') {
|
||||||
context.push(
|
context.push(['', url.host, ...url.pathSegments].join('/'));
|
||||||
['', url.host, ...url.pathSegments].join('/'),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final whitelistDomains = ['solian.app', 'solsynth.dev'];
|
final whitelistDomains = ['solian.app', 'solsynth.dev'];
|
||||||
@ -143,17 +141,27 @@ class MarkdownTextContent extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
generator: MarkdownGenerator(
|
generator: MarkdownTextContent.buildGenerator(
|
||||||
generators: [latexGenerator],
|
isDark: isDark,
|
||||||
inlineSyntaxList: [
|
linesMargin: linesMargin,
|
||||||
_UserNameCardInlineSyntax(),
|
|
||||||
_StickerInlineSyntax(),
|
|
||||||
LatexSyntax(isDark),
|
|
||||||
],
|
|
||||||
linesMargin: linesMargin ?? EdgeInsets.symmetric(vertical: 4),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MarkdownGenerator buildGenerator({
|
||||||
|
bool isDark = false,
|
||||||
|
EdgeInsets? linesMargin,
|
||||||
|
}) {
|
||||||
|
return MarkdownGenerator(
|
||||||
|
generators: [latexGenerator],
|
||||||
|
inlineSyntaxList: [
|
||||||
|
_UserNameCardInlineSyntax(),
|
||||||
|
_StickerInlineSyntax(),
|
||||||
|
LatexSyntax(isDark),
|
||||||
|
],
|
||||||
|
linesMargin: linesMargin ?? EdgeInsets.symmetric(vertical: 4),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _UserNameCardInlineSyntax extends markdown.InlineSyntax {
|
class _UserNameCardInlineSyntax extends markdown.InlineSyntax {
|
||||||
|
33
lib/widgets/loading_indicator.dart
Normal file
33
lib/widgets/loading_indicator.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A simple loading indicator widget that can be used throughout the app
|
||||||
|
class LoadingIndicator extends StatelessWidget {
|
||||||
|
/// The size of the loading indicator
|
||||||
|
final double size;
|
||||||
|
|
||||||
|
/// The color of the loading indicator
|
||||||
|
final Color? color;
|
||||||
|
|
||||||
|
/// Creates a loading indicator
|
||||||
|
const LoadingIndicator({
|
||||||
|
super.key,
|
||||||
|
this.size = 24.0,
|
||||||
|
this.color,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2.0,
|
||||||
|
valueColor: color != null
|
||||||
|
? AlwaysStoppedAnimation<Color>(
|
||||||
|
color!,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
139
lib/widgets/web_article_card.dart
Normal file
139
lib/widgets/web_article_card.dart
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:island/models/webfeed.dart';
|
||||||
|
import 'package:island/services/time.dart';
|
||||||
|
|
||||||
|
class WebArticleCard extends StatelessWidget {
|
||||||
|
final SnWebArticle article;
|
||||||
|
final double? maxWidth;
|
||||||
|
final bool showDetails;
|
||||||
|
|
||||||
|
const WebArticleCard({
|
||||||
|
super.key,
|
||||||
|
required this.article,
|
||||||
|
this.maxWidth,
|
||||||
|
this.showDetails = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
void _onTap(BuildContext context) {
|
||||||
|
context.push('/feeds/articles/${article.id}');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final colorScheme = theme.colorScheme;
|
||||||
|
|
||||||
|
return ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => _onTap(context),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
// Image or fallback
|
||||||
|
article.preview?.imageUrl != null
|
||||||
|
? CachedNetworkImage(
|
||||||
|
imageUrl: article.preview!.imageUrl!,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
)
|
||||||
|
: ColoredBox(
|
||||||
|
color: colorScheme.secondaryContainer,
|
||||||
|
child: const Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.article_outlined,
|
||||||
|
size: 48,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Gradient overlay
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
Colors.transparent,
|
||||||
|
Colors.black.withOpacity(0.7),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Title
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomLeft,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 12,
|
||||||
|
right: 12,
|
||||||
|
bottom: 8,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (showDetails)
|
||||||
|
const SizedBox(height: 8)
|
||||||
|
else
|
||||||
|
Spacer(),
|
||||||
|
Text(
|
||||||
|
article.title,
|
||||||
|
style: theme.textTheme.titleSmall?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
height: 1.3,
|
||||||
|
),
|
||||||
|
maxLines: showDetails ? 3 : 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
if (showDetails &&
|
||||||
|
article.author?.isNotEmpty == true) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
article.author!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: Colors.white.withOpacity(0.9),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (showDetails) const Spacer(),
|
||||||
|
if (showDetails && article.publishedAt != null) ...[
|
||||||
|
Text(
|
||||||
|
'${article.publishedAt!.formatSystem()} · ${article.publishedAt!.formatRelative(context)}',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 9,
|
||||||
|
color: Colors.white70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
],
|
||||||
|
Text(
|
||||||
|
article.feed?.title ?? 'Unknown Source',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 9,
|
||||||
|
color: Colors.white70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -11,32 +11,32 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- file_selector_macos (0.0.1):
|
- file_selector_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Firebase/CoreOnly (11.13.0):
|
- Firebase/CoreOnly (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- Firebase/Messaging (11.13.0):
|
- Firebase/Messaging (11.15.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 11.13.0)
|
- FirebaseMessaging (~> 11.15.0)
|
||||||
- firebase_core (3.14.0):
|
- firebase_core (3.15.0):
|
||||||
- Firebase/CoreOnly (~> 11.13.0)
|
- Firebase/CoreOnly (~> 11.15.0)
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- firebase_messaging (15.2.7):
|
- firebase_messaging (15.2.8):
|
||||||
- Firebase/CoreOnly (~> 11.13.0)
|
- Firebase/CoreOnly (~> 11.15.0)
|
||||||
- Firebase/Messaging (~> 11.13.0)
|
- Firebase/Messaging (~> 11.15.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- FirebaseCore (11.13.0):
|
- FirebaseCore (11.15.0):
|
||||||
- FirebaseCoreInternal (~> 11.13.0)
|
- FirebaseCoreInternal (~> 11.15.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
- FirebaseCoreInternal (11.13.0):
|
- FirebaseCoreInternal (11.15.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- FirebaseInstallations (11.13.0):
|
- FirebaseInstallations (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseMessaging (11.13.0):
|
- FirebaseMessaging (11.15.0):
|
||||||
- FirebaseCore (~> 11.13.0)
|
- FirebaseCore (~> 11.15.0)
|
||||||
- FirebaseInstallations (~> 11.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleDataTransport (~> 10.0)
|
- GoogleDataTransport (~> 10.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
@ -92,7 +92,7 @@ PODS:
|
|||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- irondash_engine_context (0.0.1):
|
- irondash_engine_context (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- livekit_client (2.4.8):
|
- livekit_client (2.4.9):
|
||||||
- flutter_webrtc
|
- flutter_webrtc
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- WebRTC-SDK (= 125.6422.07)
|
- WebRTC-SDK (= 125.6422.07)
|
||||||
@ -291,13 +291,13 @@ SPEC CHECKSUMS:
|
|||||||
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
||||||
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
|
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
|
||||||
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
|
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
|
||||||
Firebase: 3435bc66b4d494c2f22c79fd3aae4c1db6662327
|
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
|
||||||
firebase_core: 1095fcf33161d99bc34aa10f7c0d89414a208d15
|
firebase_core: 177f51be1650b15d2d5b9f1abf48792619288070
|
||||||
firebase_messaging: 6417056ffb85141607618ddfef9fec9f3caab3ea
|
firebase_messaging: 8748a5d4bb435993cffa7f5501292f3e914a23d7
|
||||||
FirebaseCore: c692c7f1c75305ab6aff2b367f25e11d73aa8bd0
|
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
|
||||||
FirebaseCoreInternal: 29d7b3af4aaf0b8f3ed20b568c13df399b06f68c
|
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
|
||||||
FirebaseInstallations: 0ee9074f2c1e86561ace168ee1470dc67aabaf02
|
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
|
||||||
FirebaseMessaging: 195bbdb73e6ca1dbc76cd46e73f3552c084ef6e4
|
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
|
||||||
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
|
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
|
||||||
flutter_platform_alert: 8fa7a7c21f95b26d08b4a3891936ca27e375f284
|
flutter_platform_alert: 8fa7a7c21f95b26d08b4a3891936ca27e375f284
|
||||||
flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54
|
flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54
|
||||||
@ -309,7 +309,7 @@ SPEC CHECKSUMS:
|
|||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba
|
irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba
|
||||||
livekit_client: 6a35243df3da61750c98e266e02dedcf5d25c888
|
livekit_client: c9d9f41996f5cf22b9ba0e8483e6af4ca5094059
|
||||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||||
media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
|
media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
|
||||||
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
|
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
|
||||||
|
140
pubspec.lock
140
pubspec.lock
@ -13,10 +13,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _flutterfire_internals
|
name: _flutterfire_internals
|
||||||
sha256: dda4fd7909a732a014239009aa52537b136f8ce568de23c212587097887e2307
|
sha256: "50e24b769bd1e725732f0aff18b806b8731c1fbcf4e8018ab98e7c4805a2a52f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.56"
|
version: "1.3.57"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -629,50 +629,50 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_core
|
name: firebase_core
|
||||||
sha256: "420d9111dcf095341f1ea8fdce926eef750cf7b9745d21f38000de780c94f608"
|
sha256: "5bba5924139e91d26446fd2601c18a6aa62c1161c768a989bb5e245dcdc20644"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.14.0"
|
version: "3.15.0"
|
||||||
firebase_core_platform_interface:
|
firebase_core_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_platform_interface
|
name: firebase_core_platform_interface
|
||||||
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
|
sha256: "5d2ab45779d91af2aa0252dec9fe4ee1caa015d83377de255454dcaa1526a0e0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.4.0"
|
version: "5.4.1"
|
||||||
firebase_core_web:
|
firebase_core_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_web
|
name: firebase_core_web
|
||||||
sha256: ddd72baa6f727e5b23f32d9af23d7d453d67946f380bd9c21daf474ee0f7326e
|
sha256: eb3afccfc452b2b2075acbe0c4b27de62dd596802b4e5e19869c1e926cbb20b3
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.23.0"
|
version: "2.24.0"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
sha256: "758461f67b96aa5ad27625aaae39882fd6d1961b1c7e005301f9a74b6336100b"
|
sha256: c6711cf2f455532b84a94022c7aaf85088849763af2f01b775ca79d82d10a01a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.7"
|
version: "15.2.8"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_platform_interface
|
name: firebase_messaging_platform_interface
|
||||||
sha256: "614db1b0df0f53e541e41cc182b6d7ede5763c400f6ba232a5f8d0e1b5e5de32"
|
sha256: "1c9dacccb1aee1bf17ba519dda5563a16fdd2ec1e79b5f2e421cb4bf75a166f7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.6.7"
|
version: "4.6.8"
|
||||||
firebase_messaging_web:
|
firebase_messaging_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_web
|
name: firebase_messaging_web
|
||||||
sha256: b5fbbcdd3e0e7f3fde72b0c119410f22737638fed5fc428b54bba06bc1455d81
|
sha256: "54317c26fa92f0d90a2017977ac791cb0504eca29fcf397f06adf727d4a7a2d5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.7"
|
version: "3.10.8"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -798,6 +798,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.0"
|
version: "0.6.0"
|
||||||
|
flutter_keyboard_visibility:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility
|
||||||
|
sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.0"
|
||||||
|
flutter_keyboard_visibility_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility_linux
|
||||||
|
sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
flutter_keyboard_visibility_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility_macos
|
||||||
|
sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
flutter_keyboard_visibility_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility_platform_interface
|
||||||
|
sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
flutter_keyboard_visibility_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility_web
|
||||||
|
sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
flutter_keyboard_visibility_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_keyboard_visibility_windows
|
||||||
|
sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -960,6 +1008,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.1"
|
version: "4.1.1"
|
||||||
|
flutter_typeahead:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_typeahead
|
||||||
|
sha256: d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.0"
|
||||||
flutter_udid:
|
flutter_udid:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -977,10 +1033,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_webrtc
|
name: flutter_webrtc
|
||||||
sha256: dd47ca103b5b6217771e6277882674276d9621bbf9eb23da3c03898b507844e3
|
sha256: "792aa1e5838a719f29ae52c0773dbb5dd781fc33b1bf87c321b274e55ab51ad1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.14.1"
|
version: "0.14.2"
|
||||||
font_awesome_flutter:
|
font_awesome_flutter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1093,6 +1149,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.6"
|
version: "0.15.6"
|
||||||
|
html2md:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: html2md
|
||||||
|
sha256: "465cf8ffa1b510fe0e97941579bf5b22e2d575f2cecb500a9c0254efe33a8036"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.2"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1297,10 +1361,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: livekit_client
|
name: livekit_client
|
||||||
sha256: c270720a49b935591960c6f3296fd8f00c09b45a70cd64aef78cd0a8f8257913
|
sha256: "5d182f40cc9aafce60a9acf936bad8bc69010b5cbf0a949f6f27dc4390f2fcce"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.8"
|
version: "2.4.9"
|
||||||
local_auth:
|
local_auth:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1677,6 +1741,38 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
pointer_interceptor:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor
|
||||||
|
sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.1+2"
|
||||||
|
pointer_interceptor_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_ios
|
||||||
|
sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.1"
|
||||||
|
pointer_interceptor_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_platform_interface
|
||||||
|
sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.0+1"
|
||||||
|
pointer_interceptor_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_web
|
||||||
|
sha256: "460b600e71de6fcea2b3d5f662c92293c049c4319e27f0829310e5a953b3ee2a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.3"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1689,10 +1785,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: posix
|
name: posix
|
||||||
sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62
|
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "6.0.3"
|
||||||
protobuf:
|
protobuf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1809,10 +1905,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_web
|
name: record_web
|
||||||
sha256: "024c81eb7f51468b1833a3eca8b461c7ca25c04899dba37abe580bb57afd32e4"
|
sha256: a12856d0b3dd03d336b4b10d7520a8b3e21649a06a8f95815318feaa8f07adbb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.8"
|
version: "1.1.9"
|
||||||
record_windows:
|
record_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 3.0.0+109
|
version: 3.0.0+110
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.7.2
|
sdk: ^3.7.2
|
||||||
@ -37,7 +37,7 @@ dependencies:
|
|||||||
flutter_hooks: ^0.21.2
|
flutter_hooks: ^0.21.2
|
||||||
hooks_riverpod: ^2.6.1
|
hooks_riverpod: ^2.6.1
|
||||||
bitsdojo_window: ^0.1.6
|
bitsdojo_window: ^0.1.6
|
||||||
go_router: ^15.2.4
|
go_router: ^15.1.3
|
||||||
styled_widget: ^0.4.1
|
styled_widget: ^0.4.1
|
||||||
shared_preferences: ^2.5.3
|
shared_preferences: ^2.5.3
|
||||||
flutter_riverpod: ^2.6.1
|
flutter_riverpod: ^2.6.1
|
||||||
@ -127,6 +127,8 @@ dependencies:
|
|||||||
url: https://github.com/lionelmennig/textfield_tags.git
|
url: https://github.com/lionelmennig/textfield_tags.git
|
||||||
ref: fixes/allow-controller-re-registration
|
ref: fixes/allow-controller-re-registration
|
||||||
mime: ^2.0.0
|
mime: ^2.0.0
|
||||||
|
html2md: ^1.3.2
|
||||||
|
flutter_typeahead: ^5.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user