♻️ Continued to migrate list pagination
This commit is contained in:
@@ -4,60 +4,51 @@ import 'package:gap/gap.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/poll.dart';
|
import 'package:island/models/poll.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/screens/poll/poll_editor.dart';
|
import 'package:island/screens/poll/poll_editor.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:island/widgets/poll/poll_feedback.dart';
|
import 'package:island/widgets/poll/poll_feedback.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'poll_list.g.dart';
|
part 'poll_list.g.dart';
|
||||||
|
|
||||||
@riverpod
|
final pollListNotifierProvider = AsyncNotifierProvider.family.autoDispose(
|
||||||
class PollListNotifier extends _$PollListNotifier
|
PollListNotifier.new,
|
||||||
with CursorPagingNotifierMixin<SnPollWithStats> {
|
);
|
||||||
static const int _pageSize = 20;
|
|
||||||
|
class PollListNotifier
|
||||||
|
extends AutoDisposeFamilyAsyncNotifier<List<SnPollWithStats>, String?>
|
||||||
|
with FamilyAsyncPaginationController<SnPollWithStats, String?> {
|
||||||
|
static const int pageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnPollWithStats>> build(String? pubName) {
|
Future<List<SnPollWithStats>> fetch() async {
|
||||||
// immediately load first page
|
|
||||||
return fetch(cursor: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CursorPagingData<SnPollWithStats>> fetch({
|
|
||||||
required String? cursor,
|
|
||||||
}) async {
|
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
// read the current family argument passed to provider
|
// read the current family argument passed to provider
|
||||||
final currentPub = pubName;
|
|
||||||
final queryParams = {
|
final queryParams = {
|
||||||
'offset': offset,
|
'offset': fetchedCount.toString(),
|
||||||
'take': _pageSize,
|
'take': pageSize,
|
||||||
if (currentPub != null) 'pub': currentPub,
|
if (arg != null) 'pub': arg,
|
||||||
};
|
};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/sphere/polls/me',
|
'/sphere/polls/me',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
final List<dynamic> data = response.data;
|
final items =
|
||||||
final items = data.map((json) => SnPollWithStats.fromJson(json)).toList();
|
response.data
|
||||||
|
.map((json) => SnPollWithStats.fromJson(json))
|
||||||
|
.cast<SnPollWithStats>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
final hasMore = offset + items.length < total;
|
return items;
|
||||||
final nextCursor = hasMore ? (offset + items.length).toString() : null;
|
|
||||||
|
|
||||||
return CursorPagingData(
|
|
||||||
items: items,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,20 +88,11 @@ class CreatorPollListScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: ExtendedRefreshIndicator(
|
body: ExtendedRefreshIndicator(
|
||||||
onRefresh: () => ref.refresh(pollListNotifierProvider(pubName).future),
|
onRefresh: () => ref.refresh(pollListNotifierProvider(pubName).future),
|
||||||
child: CustomScrollView(
|
child: PaginationList(
|
||||||
slivers: [
|
|
||||||
PagingHelperSliverView(
|
|
||||||
provider: pollListNotifierProvider(pubName),
|
provider: pollListNotifierProvider(pubName),
|
||||||
futureRefreshable: pollListNotifierProvider(pubName).future,
|
notifier: pollListNotifierProvider(pubName).notifier,
|
||||||
notifierRefreshable: pollListNotifierProvider(pubName).notifier,
|
padding: const EdgeInsets.only(top: 12),
|
||||||
contentBuilder:
|
itemBuilder: (context, index, pollWithStats) {
|
||||||
(data, widgetCount, endItemView) => SliverList.builder(
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
final pollWithStats = data.items[index];
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxWidth: 640),
|
constraints: BoxConstraints(maxWidth: 640),
|
||||||
child: _CreatorPollItem(
|
child: _CreatorPollItem(
|
||||||
@@ -121,9 +103,6 @@ class CreatorPollListScreen extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,154 +148,5 @@ class _PollWithStatsProviderElement
|
|||||||
String get id => (origin as PollWithStatsProvider).id;
|
String get id => (origin as PollWithStatsProvider).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$pollListNotifierHash() => r'd5b822e737788be8982f5cb3b501d460441930c1';
|
|
||||||
|
|
||||||
abstract class _$PollListNotifier
|
|
||||||
extends
|
|
||||||
BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnPollWithStats>> {
|
|
||||||
late final String? pubName;
|
|
||||||
|
|
||||||
FutureOr<CursorPagingData<SnPollWithStats>> build(String? pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
@ProviderFor(PollListNotifier)
|
|
||||||
const pollListNotifierProvider = PollListNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
class PollListNotifierFamily
|
|
||||||
extends Family<AsyncValue<CursorPagingData<SnPollWithStats>>> {
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
const PollListNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
PollListNotifierProvider call(String? pubName) {
|
|
||||||
return PollListNotifierProvider(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
PollListNotifierProvider getProviderOverride(
|
|
||||||
covariant PollListNotifierProvider provider,
|
|
||||||
) {
|
|
||||||
return call(provider.pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
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'pollListNotifierProvider';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
class PollListNotifierProvider
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderImpl<
|
|
||||||
PollListNotifier,
|
|
||||||
CursorPagingData<SnPollWithStats>
|
|
||||||
> {
|
|
||||||
/// See also [PollListNotifier].
|
|
||||||
PollListNotifierProvider(String? pubName)
|
|
||||||
: this._internal(
|
|
||||||
() => PollListNotifier()..pubName = pubName,
|
|
||||||
from: pollListNotifierProvider,
|
|
||||||
name: r'pollListNotifierProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$pollListNotifierHash,
|
|
||||||
dependencies: PollListNotifierFamily._dependencies,
|
|
||||||
allTransitiveDependencies:
|
|
||||||
PollListNotifierFamily._allTransitiveDependencies,
|
|
||||||
pubName: pubName,
|
|
||||||
);
|
|
||||||
|
|
||||||
PollListNotifierProvider._internal(
|
|
||||||
super._createNotifier, {
|
|
||||||
required super.name,
|
|
||||||
required super.dependencies,
|
|
||||||
required super.allTransitiveDependencies,
|
|
||||||
required super.debugGetCreateSourceHash,
|
|
||||||
required super.from,
|
|
||||||
required this.pubName,
|
|
||||||
}) : super.internal();
|
|
||||||
|
|
||||||
final String? pubName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FutureOr<CursorPagingData<SnPollWithStats>> runNotifierBuild(
|
|
||||||
covariant PollListNotifier notifier,
|
|
||||||
) {
|
|
||||||
return notifier.build(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Override overrideWith(PollListNotifier Function() create) {
|
|
||||||
return ProviderOverride(
|
|
||||||
origin: this,
|
|
||||||
override: PollListNotifierProvider._internal(
|
|
||||||
() => create()..pubName = pubName,
|
|
||||||
from: from,
|
|
||||||
name: null,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
debugGetCreateSourceHash: null,
|
|
||||||
pubName: pubName,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
PollListNotifier,
|
|
||||||
CursorPagingData<SnPollWithStats>
|
|
||||||
>
|
|
||||||
createElement() {
|
|
||||||
return _PollListNotifierProviderElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is PollListNotifierProvider && other.pubName == pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
|
||||||
hash = _SystemHash.combine(hash, pubName.hashCode);
|
|
||||||
|
|
||||||
return _SystemHash.finish(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
mixin PollListNotifierRef
|
|
||||||
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnPollWithStats>> {
|
|
||||||
/// The parameter `pubName` of this provider.
|
|
||||||
String? get pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PollListNotifierProviderElement
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
PollListNotifier,
|
|
||||||
CursorPagingData<SnPollWithStats>
|
|
||||||
>
|
|
||||||
with PollListNotifierRef {
|
|
||||||
_PollListNotifierProviderElement(super.provider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String? get pubName => (origin as PollListNotifierProvider).pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// 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
|
// 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
|
||||||
|
|||||||
@@ -6,54 +6,43 @@ import 'package:google_fonts/google_fonts.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/publication_site.dart';
|
import 'package:island/models/publication_site.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/screens/creators/sites/site_edit.dart';
|
import 'package:island/screens/creators/sites/site_edit.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'site_list.g.dart';
|
final siteListNotifierProvider = AsyncNotifierProvider.family.autoDispose(
|
||||||
|
SiteListNotifier.new,
|
||||||
|
);
|
||||||
|
|
||||||
@riverpod
|
class SiteListNotifier
|
||||||
class SiteListNotifier extends _$SiteListNotifier
|
extends AutoDisposeFamilyAsyncNotifier<List<SnPublicationSite>, String>
|
||||||
with CursorPagingNotifierMixin<SnPublicationSite> {
|
with FamilyAsyncPaginationController<SnPublicationSite, String> {
|
||||||
static const int _pageSize = 20;
|
static const int pageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnPublicationSite>> build(String? pubName) {
|
Future<List<SnPublicationSite>> fetch() async {
|
||||||
// immediately load first page
|
|
||||||
return fetch(cursor: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CursorPagingData<SnPublicationSite>> fetch({
|
|
||||||
required String? cursor,
|
|
||||||
}) async {
|
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
// read the current family argument passed to provider
|
// read the current family argument passed to provider
|
||||||
final queryParams = {'offset': offset, 'take': _pageSize};
|
final queryParams = {'offset': fetchedCount.toString(), 'take': pageSize};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/zone/sites/$pubName',
|
'/zone/sites/$arg',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
final List<dynamic> data = response.data;
|
final items =
|
||||||
final items = data.map((json) => SnPublicationSite.fromJson(json)).toList();
|
response.data
|
||||||
|
.map((json) => SnPublicationSite.fromJson(json))
|
||||||
|
.cast<SnPublicationSite>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
final hasMore = offset + items.length < total;
|
return items;
|
||||||
final nextCursor = hasMore ? (offset + items.length).toString() : null;
|
|
||||||
|
|
||||||
return CursorPagingData(
|
|
||||||
items: items,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,25 +73,16 @@ class CreatorSiteListScreen extends HookConsumerWidget {
|
|||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
const SliverGap(8),
|
const SliverGap(8),
|
||||||
PagingHelperSliverView(
|
PaginationList(
|
||||||
provider: siteListNotifierProvider(pubName),
|
provider: siteListNotifierProvider(pubName),
|
||||||
futureRefreshable: siteListNotifierProvider(pubName).future,
|
notifier: siteListNotifierProvider(pubName).notifier,
|
||||||
notifierRefreshable: siteListNotifierProvider(pubName).notifier,
|
itemBuilder: (context, index, site) {
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => SliverList.builder(
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
final site = data.items[index];
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxWidth: 640),
|
constraints: BoxConstraints(maxWidth: 640),
|
||||||
child: _CreatorSiteItem(site: site, pubName: pubName),
|
child: _CreatorSiteItem(site: site, pubName: pubName),
|
||||||
).center();
|
).center();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'site_list.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// RiverpodGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
String _$siteListNotifierHash() => r'1670cadcc0c7ccbd98bc33bbf5b4af21e9cb166c';
|
|
||||||
|
|
||||||
/// 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 _$SiteListNotifier
|
|
||||||
extends
|
|
||||||
BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnPublicationSite>> {
|
|
||||||
late final String? pubName;
|
|
||||||
|
|
||||||
FutureOr<CursorPagingData<SnPublicationSite>> build(String? pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
@ProviderFor(SiteListNotifier)
|
|
||||||
const siteListNotifierProvider = SiteListNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
class SiteListNotifierFamily
|
|
||||||
extends Family<AsyncValue<CursorPagingData<SnPublicationSite>>> {
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
const SiteListNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
SiteListNotifierProvider call(String? pubName) {
|
|
||||||
return SiteListNotifierProvider(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
SiteListNotifierProvider getProviderOverride(
|
|
||||||
covariant SiteListNotifierProvider provider,
|
|
||||||
) {
|
|
||||||
return call(provider.pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
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'siteListNotifierProvider';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
class SiteListNotifierProvider
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderImpl<
|
|
||||||
SiteListNotifier,
|
|
||||||
CursorPagingData<SnPublicationSite>
|
|
||||||
> {
|
|
||||||
/// See also [SiteListNotifier].
|
|
||||||
SiteListNotifierProvider(String? pubName)
|
|
||||||
: this._internal(
|
|
||||||
() => SiteListNotifier()..pubName = pubName,
|
|
||||||
from: siteListNotifierProvider,
|
|
||||||
name: r'siteListNotifierProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$siteListNotifierHash,
|
|
||||||
dependencies: SiteListNotifierFamily._dependencies,
|
|
||||||
allTransitiveDependencies:
|
|
||||||
SiteListNotifierFamily._allTransitiveDependencies,
|
|
||||||
pubName: pubName,
|
|
||||||
);
|
|
||||||
|
|
||||||
SiteListNotifierProvider._internal(
|
|
||||||
super._createNotifier, {
|
|
||||||
required super.name,
|
|
||||||
required super.dependencies,
|
|
||||||
required super.allTransitiveDependencies,
|
|
||||||
required super.debugGetCreateSourceHash,
|
|
||||||
required super.from,
|
|
||||||
required this.pubName,
|
|
||||||
}) : super.internal();
|
|
||||||
|
|
||||||
final String? pubName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FutureOr<CursorPagingData<SnPublicationSite>> runNotifierBuild(
|
|
||||||
covariant SiteListNotifier notifier,
|
|
||||||
) {
|
|
||||||
return notifier.build(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Override overrideWith(SiteListNotifier Function() create) {
|
|
||||||
return ProviderOverride(
|
|
||||||
origin: this,
|
|
||||||
override: SiteListNotifierProvider._internal(
|
|
||||||
() => create()..pubName = pubName,
|
|
||||||
from: from,
|
|
||||||
name: null,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
debugGetCreateSourceHash: null,
|
|
||||||
pubName: pubName,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
SiteListNotifier,
|
|
||||||
CursorPagingData<SnPublicationSite>
|
|
||||||
>
|
|
||||||
createElement() {
|
|
||||||
return _SiteListNotifierProviderElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is SiteListNotifierProvider && other.pubName == pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
|
||||||
hash = _SystemHash.combine(hash, pubName.hashCode);
|
|
||||||
|
|
||||||
return _SystemHash.finish(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
mixin SiteListNotifierRef
|
|
||||||
on
|
|
||||||
AutoDisposeAsyncNotifierProviderRef<
|
|
||||||
CursorPagingData<SnPublicationSite>
|
|
||||||
> {
|
|
||||||
/// The parameter `pubName` of this provider.
|
|
||||||
String? get pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SiteListNotifierProviderElement
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
SiteListNotifier,
|
|
||||||
CursorPagingData<SnPublicationSite>
|
|
||||||
>
|
|
||||||
with SiteListNotifierRef {
|
|
||||||
_SiteListNotifierProviderElement(super.provider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String? get pubName => (origin as SiteListNotifierProvider).pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
@@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:island/models/file.dart';
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/models/sticker.dart';
|
import 'package:island/models/sticker.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/services/responsive.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
@@ -14,10 +15,10 @@ import 'package:island/widgets/content/cloud_file_picker.dart';
|
|||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/content/sheet.dart';
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
import 'package:island/screens/creators/stickers/pack_detail.dart';
|
import 'package:island/screens/creators/stickers/pack_detail.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
|
|
||||||
part 'stickers.g.dart';
|
part 'stickers.g.dart';
|
||||||
|
|
||||||
@@ -81,20 +82,10 @@ class SliverStickerPacksList extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return PagingHelperView(
|
return PaginationList(
|
||||||
provider: stickerPacksNotifierProvider(pubName),
|
provider: stickerPacksNotifierProvider(pubName),
|
||||||
futureRefreshable: stickerPacksNotifierProvider(pubName).future,
|
notifier: stickerPacksNotifierProvider(pubName).notifier,
|
||||||
notifierRefreshable: stickerPacksNotifierProvider(pubName).notifier,
|
itemBuilder: (context, index, sticker) {
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => ListView.builder(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
final sticker = data.items[index];
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
@@ -124,9 +115,7 @@ class SliverStickerPacksList extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
ref.invalidate(
|
ref.invalidate(stickerPackContentProvider(id));
|
||||||
stickerPackContentProvider(id),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -146,46 +135,41 @@ class SliverStickerPacksList extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
final stickerPacksNotifierProvider = AsyncNotifierProvider.family.autoDispose(
|
||||||
class StickerPacksNotifier extends _$StickerPacksNotifier
|
StickerPacksNotifier.new,
|
||||||
with CursorPagingNotifierMixin<SnStickerPack> {
|
);
|
||||||
static const int _pageSize = 20;
|
|
||||||
|
class StickerPacksNotifier
|
||||||
|
extends AutoDisposeFamilyAsyncNotifier<List<SnStickerPack>, String>
|
||||||
|
with FamilyAsyncPaginationController<SnStickerPack, String> {
|
||||||
|
static const int pageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnStickerPack>> build(String pubName) {
|
Future<List<SnStickerPack>> fetch() async {
|
||||||
return fetch(cursor: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CursorPagingData<SnStickerPack>> fetch({
|
|
||||||
required String? cursor,
|
|
||||||
}) async {
|
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/sphere/stickers',
|
'/sphere/stickers',
|
||||||
queryParameters: {'offset': offset, 'take': _pageSize, 'pub': pubName},
|
queryParameters: {
|
||||||
|
'offset': fetchedCount.toString(),
|
||||||
|
'take': pageSize,
|
||||||
|
'pub': arg,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
final List<dynamic> data = response.data;
|
final stickers =
|
||||||
final stickers = data.map((e) => SnStickerPack.fromJson(e)).toList();
|
response.data
|
||||||
|
.map((e) => SnStickerPack.fromJson(e))
|
||||||
|
.cast<SnStickerPack>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
final hasMore = offset + stickers.length < total;
|
return stickers;
|
||||||
final nextCursor = hasMore ? (offset + stickers.length).toString() : null;
|
|
||||||
|
|
||||||
return CursorPagingData(
|
|
||||||
items: stickers,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,154 +147,5 @@ class _StickerPackProviderElement
|
|||||||
String? get packId => (origin as StickerPackProvider).packId;
|
String? get packId => (origin as StickerPackProvider).packId;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$stickerPacksNotifierHash() =>
|
|
||||||
r'30024b35235f3085a5b1ec2204d0a974ee907e22';
|
|
||||||
|
|
||||||
abstract class _$StickerPacksNotifier
|
|
||||||
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnStickerPack>> {
|
|
||||||
late final String pubName;
|
|
||||||
|
|
||||||
FutureOr<CursorPagingData<SnStickerPack>> build(String pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
@ProviderFor(StickerPacksNotifier)
|
|
||||||
const stickerPacksNotifierProvider = StickerPacksNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
class StickerPacksNotifierFamily
|
|
||||||
extends Family<AsyncValue<CursorPagingData<SnStickerPack>>> {
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
const StickerPacksNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
StickerPacksNotifierProvider call(String pubName) {
|
|
||||||
return StickerPacksNotifierProvider(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
StickerPacksNotifierProvider getProviderOverride(
|
|
||||||
covariant StickerPacksNotifierProvider provider,
|
|
||||||
) {
|
|
||||||
return call(provider.pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
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'stickerPacksNotifierProvider';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
class StickerPacksNotifierProvider
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderImpl<
|
|
||||||
StickerPacksNotifier,
|
|
||||||
CursorPagingData<SnStickerPack>
|
|
||||||
> {
|
|
||||||
/// See also [StickerPacksNotifier].
|
|
||||||
StickerPacksNotifierProvider(String pubName)
|
|
||||||
: this._internal(
|
|
||||||
() => StickerPacksNotifier()..pubName = pubName,
|
|
||||||
from: stickerPacksNotifierProvider,
|
|
||||||
name: r'stickerPacksNotifierProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$stickerPacksNotifierHash,
|
|
||||||
dependencies: StickerPacksNotifierFamily._dependencies,
|
|
||||||
allTransitiveDependencies:
|
|
||||||
StickerPacksNotifierFamily._allTransitiveDependencies,
|
|
||||||
pubName: pubName,
|
|
||||||
);
|
|
||||||
|
|
||||||
StickerPacksNotifierProvider._internal(
|
|
||||||
super._createNotifier, {
|
|
||||||
required super.name,
|
|
||||||
required super.dependencies,
|
|
||||||
required super.allTransitiveDependencies,
|
|
||||||
required super.debugGetCreateSourceHash,
|
|
||||||
required super.from,
|
|
||||||
required this.pubName,
|
|
||||||
}) : super.internal();
|
|
||||||
|
|
||||||
final String pubName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FutureOr<CursorPagingData<SnStickerPack>> runNotifierBuild(
|
|
||||||
covariant StickerPacksNotifier notifier,
|
|
||||||
) {
|
|
||||||
return notifier.build(pubName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Override overrideWith(StickerPacksNotifier Function() create) {
|
|
||||||
return ProviderOverride(
|
|
||||||
origin: this,
|
|
||||||
override: StickerPacksNotifierProvider._internal(
|
|
||||||
() => create()..pubName = pubName,
|
|
||||||
from: from,
|
|
||||||
name: null,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
debugGetCreateSourceHash: null,
|
|
||||||
pubName: pubName,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
StickerPacksNotifier,
|
|
||||||
CursorPagingData<SnStickerPack>
|
|
||||||
>
|
|
||||||
createElement() {
|
|
||||||
return _StickerPacksNotifierProviderElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is StickerPacksNotifierProvider && other.pubName == pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
|
||||||
hash = _SystemHash.combine(hash, pubName.hashCode);
|
|
||||||
|
|
||||||
return _SystemHash.finish(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
mixin StickerPacksNotifierRef
|
|
||||||
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnStickerPack>> {
|
|
||||||
/// The parameter `pubName` of this provider.
|
|
||||||
String get pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StickerPacksNotifierProviderElement
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
StickerPacksNotifier,
|
|
||||||
CursorPagingData<SnStickerPack>
|
|
||||||
>
|
|
||||||
with StickerPacksNotifierRef {
|
|
||||||
_StickerPacksNotifierProviderElement(super.provider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get pubName => (origin as StickerPacksNotifierProvider).pubName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// 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
|
// 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
|
||||||
|
|||||||
@@ -1,41 +1,37 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_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';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:island/widgets/web_article_card.dart';
|
import 'package:island/widgets/web_article_card.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
|
|
||||||
part 'articles.g.dart';
|
part 'articles.g.dart';
|
||||||
|
part 'articles.freezed.dart';
|
||||||
|
|
||||||
@riverpod
|
@freezed
|
||||||
class ArticlesListNotifier extends _$ArticlesListNotifier
|
sealed class ArticleListQuery with _$ArticleListQuery {
|
||||||
with CursorPagingNotifierMixin<SnWebArticle> {
|
const factory ArticleListQuery({String? feedId, String? publisherId}) =
|
||||||
static const int _pageSize = 20;
|
_ArticleListQuery;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _params = {};
|
final articlesListNotifierProvider = AsyncNotifierProvider.family.autoDispose(
|
||||||
|
ArticlesListNotifier.new,
|
||||||
|
);
|
||||||
|
|
||||||
|
class ArticlesListNotifier
|
||||||
|
extends AutoDisposeFamilyAsyncNotifier<List<SnWebArticle>, ArticleListQuery>
|
||||||
|
with FamilyAsyncPaginationController<SnWebArticle, ArticleListQuery> {
|
||||||
|
static const int pageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnWebArticle>> build({
|
Future<List<SnWebArticle>> fetch() async {
|
||||||
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 client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
final queryParams = {'limit': _pageSize, 'offset': offset, ..._params};
|
final queryParams = {'limit': pageSize, 'offset': fetchedCount.toString()};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
@@ -43,23 +39,17 @@ class ArticlesListNotifier extends _$ArticlesListNotifier
|
|||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<dynamic> data = response.data;
|
|
||||||
final articles =
|
final articles =
|
||||||
data
|
response.data
|
||||||
.map(
|
.map(
|
||||||
(json) => SnWebArticle.fromJson(json as Map<String, dynamic>),
|
(json) => SnWebArticle.fromJson(json as Map<String, dynamic>),
|
||||||
)
|
)
|
||||||
|
.cast<SnWebArticle>()
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final total = int.tryParse(response.headers.value('X-Total') ?? '0') ?? 0;
|
totalCount = 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(
|
return articles;
|
||||||
items: articles,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error fetching articles: $e');
|
debugPrint('Error fetching articles: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -85,34 +75,17 @@ class SliverArticlesList extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return PagingHelperSliverView(
|
final provider = articlesListNotifierProvider(
|
||||||
provider: articlesListNotifierProvider(
|
ArticleListQuery(feedId: feedId, publisherId: publisherId),
|
||||||
feedId: feedId,
|
);
|
||||||
publisherId: publisherId,
|
return PaginationList(
|
||||||
),
|
provider: provider,
|
||||||
futureRefreshable:
|
notifier: provider.notifier,
|
||||||
articlesListNotifierProvider(
|
isRefreshable: false,
|
||||||
feedId: feedId,
|
isSliver: true,
|
||||||
publisherId: publisherId,
|
itemBuilder: (context, index, article) {
|
||||||
).future,
|
|
||||||
notifierRefreshable:
|
|
||||||
articlesListNotifierProvider(
|
|
||||||
feedId: feedId,
|
|
||||||
publisherId: publisherId,
|
|
||||||
).notifier,
|
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => SliverList.separated(
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
final article = data.items[index];
|
|
||||||
return WebArticleCard(article: article, showDetails: true);
|
return WebArticleCard(article: article, showDetails: true);
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
268
lib/screens/discovery/articles.freezed.dart
Normal file
268
lib/screens/discovery/articles.freezed.dart
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// 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 'articles.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$ArticleListQuery {
|
||||||
|
|
||||||
|
String? get feedId; String? get publisherId;
|
||||||
|
/// Create a copy of ArticleListQuery
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ArticleListQueryCopyWith<ArticleListQuery> get copyWith => _$ArticleListQueryCopyWithImpl<ArticleListQuery>(this as ArticleListQuery, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is ArticleListQuery&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,feedId,publisherId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ArticleListQuery(feedId: $feedId, publisherId: $publisherId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $ArticleListQueryCopyWith<$Res> {
|
||||||
|
factory $ArticleListQueryCopyWith(ArticleListQuery value, $Res Function(ArticleListQuery) _then) = _$ArticleListQueryCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String? feedId, String? publisherId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$ArticleListQueryCopyWithImpl<$Res>
|
||||||
|
implements $ArticleListQueryCopyWith<$Res> {
|
||||||
|
_$ArticleListQueryCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final ArticleListQuery _self;
|
||||||
|
final $Res Function(ArticleListQuery) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ArticleListQuery
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? feedId = freezed,Object? publisherId = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
feedId: freezed == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,publisherId: freezed == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [ArticleListQuery].
|
||||||
|
extension ArticleListQueryPatterns on ArticleListQuery {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ArticleListQuery value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ArticleListQuery value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery():
|
||||||
|
return $default(_that);}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ArticleListQuery value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String? feedId, String? publisherId)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery() when $default != null:
|
||||||
|
return $default(_that.feedId,_that.publisherId);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String? feedId, String? publisherId) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery():
|
||||||
|
return $default(_that.feedId,_that.publisherId);}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String? feedId, String? publisherId)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ArticleListQuery() when $default != null:
|
||||||
|
return $default(_that.feedId,_that.publisherId);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _ArticleListQuery implements ArticleListQuery {
|
||||||
|
const _ArticleListQuery({this.feedId, this.publisherId});
|
||||||
|
|
||||||
|
|
||||||
|
@override final String? feedId;
|
||||||
|
@override final String? publisherId;
|
||||||
|
|
||||||
|
/// Create a copy of ArticleListQuery
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$ArticleListQueryCopyWith<_ArticleListQuery> get copyWith => __$ArticleListQueryCopyWithImpl<_ArticleListQuery>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ArticleListQuery&&(identical(other.feedId, feedId) || other.feedId == feedId)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,feedId,publisherId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ArticleListQuery(feedId: $feedId, publisherId: $publisherId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$ArticleListQueryCopyWith<$Res> implements $ArticleListQueryCopyWith<$Res> {
|
||||||
|
factory _$ArticleListQueryCopyWith(_ArticleListQuery value, $Res Function(_ArticleListQuery) _then) = __$ArticleListQueryCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String? feedId, String? publisherId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$ArticleListQueryCopyWithImpl<$Res>
|
||||||
|
implements _$ArticleListQueryCopyWith<$Res> {
|
||||||
|
__$ArticleListQueryCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _ArticleListQuery _self;
|
||||||
|
final $Res Function(_ArticleListQuery) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ArticleListQuery
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? feedId = freezed,Object? publisherId = freezed,}) {
|
||||||
|
return _then(_ArticleListQuery(
|
||||||
|
feedId: freezed == feedId ? _self.feedId : feedId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,publisherId: freezed == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -25,201 +25,5 @@ final subscribedFeedsProvider =
|
|||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef SubscribedFeedsRef = AutoDisposeFutureProviderRef<List<SnWebFeed>>;
|
typedef SubscribedFeedsRef = AutoDisposeFutureProviderRef<List<SnWebFeed>>;
|
||||||
String _$articlesListNotifierHash() =>
|
|
||||||
r'579741af4d90c7c81f2e2697e57c4895b7a9dabc';
|
|
||||||
|
|
||||||
/// 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: 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
|
// 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
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
||||||
import 'package:gap/gap.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_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';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:island/widgets/web_article_card.dart';
|
import 'package:island/widgets/web_article_card.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'feed_detail.g.dart';
|
part 'feed_detail.g.dart';
|
||||||
@@ -23,52 +22,32 @@ Future<SnWebFeed> marketplaceWebFeed(Ref ref, String feedId) async {
|
|||||||
return SnWebFeed.fromJson(resp.data);
|
return SnWebFeed.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provider for web feed articles content
|
final marketplaceWebFeedContentNotifierProvider = AsyncNotifierProvider.family
|
||||||
@riverpod
|
.autoDispose(MarketplaceWebFeedContentNotifier.new);
|
||||||
|
|
||||||
class MarketplaceWebFeedContentNotifier
|
class MarketplaceWebFeedContentNotifier
|
||||||
extends _$MarketplaceWebFeedContentNotifier
|
extends AutoDisposeFamilyAsyncNotifier<List<SnWebArticle>, String>
|
||||||
with CursorPagingNotifierMixin<SnWebArticle> {
|
with FamilyAsyncPaginationController<SnWebArticle, String> {
|
||||||
static const int _pageSize = 20;
|
static const int pageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnWebArticle>> build(String feedId) async {
|
Future<List<SnWebArticle>> fetch() async {
|
||||||
_feedId = feedId;
|
|
||||||
return fetch(cursor: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final String _feedId;
|
|
||||||
ValueNotifier<int> totalCount = ValueNotifier(0);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CursorPagingData<SnWebArticle>> fetch({
|
|
||||||
required String? cursor,
|
|
||||||
}) async {
|
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
final queryParams = {'offset': offset, 'take': _pageSize};
|
final queryParams = {'offset': fetchedCount.toString(), 'take': pageSize};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/sphere/feeds/$_feedId/articles',
|
'/sphere/feeds/$arg/articles',
|
||||||
queryParameters: queryParams,
|
queryParameters: queryParams,
|
||||||
);
|
);
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
totalCount.value = total;
|
final articles =
|
||||||
final List<dynamic> data = response.data;
|
response.data
|
||||||
final articles = data.map((json) => SnWebArticle.fromJson(json)).toList();
|
.map((json) => SnWebArticle.fromJson(json))
|
||||||
|
.cast<SnWebArticle>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
final hasMore = offset + articles.length < total;
|
return articles;
|
||||||
final nextCursor = hasMore ? (offset + articles.length).toString() : null;
|
|
||||||
|
|
||||||
return CursorPagingData(
|
|
||||||
items: articles,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
totalCount.dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,10 +105,6 @@ class MarketplaceWebFeedDetailScreen extends HookConsumerWidget {
|
|||||||
marketplaceWebFeedContentNotifierProvider(id).notifier,
|
marketplaceWebFeedContentNotifierProvider(id).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() {
|
|
||||||
return feedNotifier.dispose;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(title: Text(feed.value?.title ?? 'loading'.tr())),
|
appBar: AppBar(title: Text(feed.value?.title ?? 'loading'.tr())),
|
||||||
body: Column(
|
body: Column(
|
||||||
@@ -147,13 +122,9 @@ class MarketplaceWebFeedDetailScreen extends HookConsumerWidget {
|
|||||||
spacing: 4,
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.rss_feed, size: 16),
|
const Icon(Symbols.rss_feed, size: 16),
|
||||||
ListenableBuilder(
|
Text(
|
||||||
listenable: feedNotifier.totalCount,
|
|
||||||
builder:
|
|
||||||
(context, _) => Text(
|
|
||||||
'webFeedArticleCount'.plural(
|
'webFeedArticleCount'.plural(
|
||||||
feedNotifier.totalCount.value,
|
feedNotifier.totalCount ?? 0,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -174,29 +145,12 @@ class MarketplaceWebFeedDetailScreen extends HookConsumerWidget {
|
|||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
// Articles list
|
// Articles list
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PagingHelperView(
|
child: PaginationList(
|
||||||
provider: marketplaceWebFeedContentNotifierProvider(id),
|
provider: marketplaceWebFeedContentNotifierProvider(id),
|
||||||
futureRefreshable:
|
notifier: marketplaceWebFeedContentNotifierProvider(id).notifier,
|
||||||
marketplaceWebFeedContentNotifierProvider(id).future,
|
itemBuilder: (context, index, article) {
|
||||||
notifierRefreshable:
|
|
||||||
marketplaceWebFeedContentNotifierProvider(id).notifier,
|
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => ListView.separated(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 24,
|
|
||||||
vertical: 20,
|
|
||||||
),
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
final article = data.items[index];
|
|
||||||
return WebArticleCard(article: article);
|
return WebArticleCard(article: article);
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) => const Gap(12),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
|||||||
@@ -290,169 +290,5 @@ class _MarketplaceWebFeedSubscriptionProviderElement
|
|||||||
(origin as MarketplaceWebFeedSubscriptionProvider).feedId;
|
(origin as MarketplaceWebFeedSubscriptionProvider).feedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$marketplaceWebFeedContentNotifierHash() =>
|
|
||||||
r'25688082884cb824eeff300888ba38c9748295dc';
|
|
||||||
|
|
||||||
abstract class _$MarketplaceWebFeedContentNotifier
|
|
||||||
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnWebArticle>> {
|
|
||||||
late final String feedId;
|
|
||||||
|
|
||||||
FutureOr<CursorPagingData<SnWebArticle>> build(String feedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
@ProviderFor(MarketplaceWebFeedContentNotifier)
|
|
||||||
const marketplaceWebFeedContentNotifierProvider =
|
|
||||||
MarketplaceWebFeedContentNotifierFamily();
|
|
||||||
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
class MarketplaceWebFeedContentNotifierFamily
|
|
||||||
extends Family<AsyncValue<CursorPagingData<SnWebArticle>>> {
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
const MarketplaceWebFeedContentNotifierFamily();
|
|
||||||
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
MarketplaceWebFeedContentNotifierProvider call(String feedId) {
|
|
||||||
return MarketplaceWebFeedContentNotifierProvider(feedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
MarketplaceWebFeedContentNotifierProvider getProviderOverride(
|
|
||||||
covariant MarketplaceWebFeedContentNotifierProvider provider,
|
|
||||||
) {
|
|
||||||
return call(provider.feedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
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'marketplaceWebFeedContentNotifierProvider';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
class MarketplaceWebFeedContentNotifierProvider
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderImpl<
|
|
||||||
MarketplaceWebFeedContentNotifier,
|
|
||||||
CursorPagingData<SnWebArticle>
|
|
||||||
> {
|
|
||||||
/// Provider for web feed articles content
|
|
||||||
///
|
|
||||||
/// Copied from [MarketplaceWebFeedContentNotifier].
|
|
||||||
MarketplaceWebFeedContentNotifierProvider(String feedId)
|
|
||||||
: this._internal(
|
|
||||||
() => MarketplaceWebFeedContentNotifier()..feedId = feedId,
|
|
||||||
from: marketplaceWebFeedContentNotifierProvider,
|
|
||||||
name: r'marketplaceWebFeedContentNotifierProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$marketplaceWebFeedContentNotifierHash,
|
|
||||||
dependencies: MarketplaceWebFeedContentNotifierFamily._dependencies,
|
|
||||||
allTransitiveDependencies:
|
|
||||||
MarketplaceWebFeedContentNotifierFamily._allTransitiveDependencies,
|
|
||||||
feedId: feedId,
|
|
||||||
);
|
|
||||||
|
|
||||||
MarketplaceWebFeedContentNotifierProvider._internal(
|
|
||||||
super._createNotifier, {
|
|
||||||
required super.name,
|
|
||||||
required super.dependencies,
|
|
||||||
required super.allTransitiveDependencies,
|
|
||||||
required super.debugGetCreateSourceHash,
|
|
||||||
required super.from,
|
|
||||||
required this.feedId,
|
|
||||||
}) : super.internal();
|
|
||||||
|
|
||||||
final String feedId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FutureOr<CursorPagingData<SnWebArticle>> runNotifierBuild(
|
|
||||||
covariant MarketplaceWebFeedContentNotifier notifier,
|
|
||||||
) {
|
|
||||||
return notifier.build(feedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Override overrideWith(MarketplaceWebFeedContentNotifier Function() create) {
|
|
||||||
return ProviderOverride(
|
|
||||||
origin: this,
|
|
||||||
override: MarketplaceWebFeedContentNotifierProvider._internal(
|
|
||||||
() => create()..feedId = feedId,
|
|
||||||
from: from,
|
|
||||||
name: null,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
debugGetCreateSourceHash: null,
|
|
||||||
feedId: feedId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
MarketplaceWebFeedContentNotifier,
|
|
||||||
CursorPagingData<SnWebArticle>
|
|
||||||
>
|
|
||||||
createElement() {
|
|
||||||
return _MarketplaceWebFeedContentNotifierProviderElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is MarketplaceWebFeedContentNotifierProvider &&
|
|
||||||
other.feedId == feedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
|
||||||
hash = _SystemHash.combine(hash, feedId.hashCode);
|
|
||||||
|
|
||||||
return _SystemHash.finish(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
mixin MarketplaceWebFeedContentNotifierRef
|
|
||||||
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnWebArticle>> {
|
|
||||||
/// The parameter `feedId` of this provider.
|
|
||||||
String get feedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MarketplaceWebFeedContentNotifierProviderElement
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
MarketplaceWebFeedContentNotifier,
|
|
||||||
CursorPagingData<SnWebArticle>
|
|
||||||
>
|
|
||||||
with MarketplaceWebFeedContentNotifierRef {
|
|
||||||
_MarketplaceWebFeedContentNotifierProviderElement(super.provider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get feedId =>
|
|
||||||
(origin as MarketplaceWebFeedContentNotifierProvider).feedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// 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
|
// 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
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@@ -6,52 +7,44 @@ import 'package:gap/gap.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_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';
|
||||||
|
import 'package:island/pods/paging.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
final marketplaceWebFeedsNotifierProvider = AsyncNotifierProvider(
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
MarketplaceWebFeedsNotifier.new,
|
||||||
|
);
|
||||||
|
|
||||||
part 'feed_marketplace.g.dart';
|
class MarketplaceWebFeedsNotifier extends AsyncNotifier<List<SnWebFeed>>
|
||||||
|
with
|
||||||
@riverpod
|
AsyncPaginationController<SnWebFeed>,
|
||||||
class MarketplaceWebFeedsNotifier extends _$MarketplaceWebFeedsNotifier
|
AsyncPaginationFilter<String?, SnWebFeed> {
|
||||||
with CursorPagingNotifierMixin<SnWebFeed> {
|
@override
|
||||||
String? _query;
|
String? currentFilter;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnWebFeed>> build({required String? query}) {
|
Future<List<SnWebFeed>> fetch() async {
|
||||||
_query = query;
|
|
||||||
return fetch(cursor: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<CursorPagingData<SnWebFeed>> fetch({required String? cursor}) async {
|
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
final offset = cursor == null ? 0 : int.parse(cursor);
|
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/sphere/feeds/explore',
|
'/sphere/feeds/explore',
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
'offset': offset,
|
'offset': fetchedCount.toString(),
|
||||||
'take': 20,
|
'take': 20,
|
||||||
if (_query != null && _query!.isNotEmpty) 'query': _query,
|
if (currentFilter != null && currentFilter!.isNotEmpty)
|
||||||
|
'query': currentFilter,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
final List<dynamic> data = response.data;
|
final feeds =
|
||||||
final feeds = data.map((e) => SnWebFeed.fromJson(e)).toList();
|
response.data
|
||||||
|
.map((e) => SnWebFeed.fromJson(e))
|
||||||
|
.cast<SnWebFeed>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
final hasMore = offset + feeds.length < total;
|
return feeds;
|
||||||
final nextCursor = hasMore ? (offset + feeds.length).toString() : null;
|
|
||||||
|
|
||||||
return CursorPagingData(
|
|
||||||
items: feeds,
|
|
||||||
hasMore: hasMore,
|
|
||||||
nextCursor: nextCursor,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,16 +79,8 @@ class MarketplaceWebFeedsScreen extends HookConsumerWidget {
|
|||||||
title: const Text('webFeeds').tr(),
|
title: const Text('webFeeds').tr(),
|
||||||
actions: const [Gap(8)],
|
actions: const [Gap(8)],
|
||||||
),
|
),
|
||||||
body: PagingHelperView(
|
body: Column(
|
||||||
provider: marketplaceWebFeedsNotifierProvider(query: query.value),
|
|
||||||
futureRefreshable:
|
|
||||||
marketplaceWebFeedsNotifierProvider(query: query.value).future,
|
|
||||||
notifierRefreshable:
|
|
||||||
marketplaceWebFeedsNotifierProvider(query: query.value).notifier,
|
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => Column(
|
|
||||||
children: [
|
children: [
|
||||||
// Search bar above the list
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: SearchBar(
|
child: SearchBar(
|
||||||
@@ -137,15 +122,11 @@ class MarketplaceWebFeedsScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: PaginationList(
|
||||||
|
provider: marketplaceWebFeedsNotifierProvider,
|
||||||
|
notifier: marketplaceWebFeedsNotifierProvider.notifier,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
itemCount: widgetCount,
|
itemBuilder: (context, index, feed) {
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
final feed = data.items[index];
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(feed.title),
|
title: Text(feed.title),
|
||||||
subtitle: Text(feed.description ?? ''),
|
subtitle: Text(feed.description ?? ''),
|
||||||
@@ -163,7 +144,6 @@ class MarketplaceWebFeedsScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,180 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'feed_marketplace.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// RiverpodGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
String _$marketplaceWebFeedsNotifierHash() =>
|
|
||||||
r'774b2985f2f7d61fe958f534f84e39f814327c4e';
|
|
||||||
|
|
||||||
/// 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 _$MarketplaceWebFeedsNotifier
|
|
||||||
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnWebFeed>> {
|
|
||||||
late final String? query;
|
|
||||||
|
|
||||||
FutureOr<CursorPagingData<SnWebFeed>> build({required String? query});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
@ProviderFor(MarketplaceWebFeedsNotifier)
|
|
||||||
const marketplaceWebFeedsNotifierProvider = MarketplaceWebFeedsNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
class MarketplaceWebFeedsNotifierFamily
|
|
||||||
extends Family<AsyncValue<CursorPagingData<SnWebFeed>>> {
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
const MarketplaceWebFeedsNotifierFamily();
|
|
||||||
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
MarketplaceWebFeedsNotifierProvider call({required String? query}) {
|
|
||||||
return MarketplaceWebFeedsNotifierProvider(query: query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
MarketplaceWebFeedsNotifierProvider getProviderOverride(
|
|
||||||
covariant MarketplaceWebFeedsNotifierProvider provider,
|
|
||||||
) {
|
|
||||||
return call(query: provider.query);
|
|
||||||
}
|
|
||||||
|
|
||||||
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'marketplaceWebFeedsNotifierProvider';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
class MarketplaceWebFeedsNotifierProvider
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderImpl<
|
|
||||||
MarketplaceWebFeedsNotifier,
|
|
||||||
CursorPagingData<SnWebFeed>
|
|
||||||
> {
|
|
||||||
/// See also [MarketplaceWebFeedsNotifier].
|
|
||||||
MarketplaceWebFeedsNotifierProvider({required String? query})
|
|
||||||
: this._internal(
|
|
||||||
() => MarketplaceWebFeedsNotifier()..query = query,
|
|
||||||
from: marketplaceWebFeedsNotifierProvider,
|
|
||||||
name: r'marketplaceWebFeedsNotifierProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$marketplaceWebFeedsNotifierHash,
|
|
||||||
dependencies: MarketplaceWebFeedsNotifierFamily._dependencies,
|
|
||||||
allTransitiveDependencies:
|
|
||||||
MarketplaceWebFeedsNotifierFamily._allTransitiveDependencies,
|
|
||||||
query: query,
|
|
||||||
);
|
|
||||||
|
|
||||||
MarketplaceWebFeedsNotifierProvider._internal(
|
|
||||||
super._createNotifier, {
|
|
||||||
required super.name,
|
|
||||||
required super.dependencies,
|
|
||||||
required super.allTransitiveDependencies,
|
|
||||||
required super.debugGetCreateSourceHash,
|
|
||||||
required super.from,
|
|
||||||
required this.query,
|
|
||||||
}) : super.internal();
|
|
||||||
|
|
||||||
final String? query;
|
|
||||||
|
|
||||||
@override
|
|
||||||
FutureOr<CursorPagingData<SnWebFeed>> runNotifierBuild(
|
|
||||||
covariant MarketplaceWebFeedsNotifier notifier,
|
|
||||||
) {
|
|
||||||
return notifier.build(query: query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Override overrideWith(MarketplaceWebFeedsNotifier Function() create) {
|
|
||||||
return ProviderOverride(
|
|
||||||
origin: this,
|
|
||||||
override: MarketplaceWebFeedsNotifierProvider._internal(
|
|
||||||
() => create()..query = query,
|
|
||||||
from: from,
|
|
||||||
name: null,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
debugGetCreateSourceHash: null,
|
|
||||||
query: query,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
MarketplaceWebFeedsNotifier,
|
|
||||||
CursorPagingData<SnWebFeed>
|
|
||||||
>
|
|
||||||
createElement() {
|
|
||||||
return _MarketplaceWebFeedsNotifierProviderElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is MarketplaceWebFeedsNotifierProvider && other.query == query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
|
||||||
hash = _SystemHash.combine(hash, query.hashCode);
|
|
||||||
|
|
||||||
return _SystemHash.finish(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
mixin MarketplaceWebFeedsNotifierRef
|
|
||||||
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnWebFeed>> {
|
|
||||||
/// The parameter `query` of this provider.
|
|
||||||
String? get query;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MarketplaceWebFeedsNotifierProviderElement
|
|
||||||
extends
|
|
||||||
AutoDisposeAsyncNotifierProviderElement<
|
|
||||||
MarketplaceWebFeedsNotifier,
|
|
||||||
CursorPagingData<SnWebFeed>
|
|
||||||
>
|
|
||||||
with MarketplaceWebFeedsNotifierRef {
|
|
||||||
_MarketplaceWebFeedsNotifierProviderElement(super.provider);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String? get query => (origin as MarketplaceWebFeedsNotifierProvider).query;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
@@ -9,8 +9,8 @@ import 'package:island/screens/creators/poll/poll_list.dart';
|
|||||||
import 'package:island/screens/poll/poll_editor.dart';
|
import 'package:island/screens/poll/poll_editor.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/content/sheet.dart';
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:island/widgets/paging/pagination_list.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:island/widgets/post/publishers_modal.dart';
|
import 'package:island/widgets/post/publishers_modal.dart';
|
||||||
|
|
||||||
@@ -45,23 +45,10 @@ class ComposePollSheet extends HookConsumerWidget {
|
|||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
children: [
|
children: [
|
||||||
// Link/Select existing poll list
|
// Link/Select existing poll list
|
||||||
PagingHelperView(
|
PaginationList(
|
||||||
provider: pollListNotifierProvider(pub?.name),
|
provider: pollListNotifierProvider(pub?.name),
|
||||||
futureRefreshable:
|
notifier: pollListNotifierProvider(pub?.name).notifier,
|
||||||
pollListNotifierProvider(pub?.name).future,
|
itemBuilder: (context, index, poll) {
|
||||||
notifierRefreshable:
|
|
||||||
pollListNotifierProvider(pub?.name).notifier,
|
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => ListView.builder(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
final poll = data.items[index];
|
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: const Icon(Symbols.how_to_vote, fill: 1),
|
leading: const Icon(Symbols.how_to_vote, fill: 1),
|
||||||
title: Text(poll.title ?? 'untitled'.tr()),
|
title: Text(poll.title ?? 'untitled'.tr()),
|
||||||
@@ -74,7 +61,6 @@ class ComposePollSheet extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
|
||||||
// Create new poll and return it
|
// Create new poll and return it
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
|
|||||||
Reference in New Issue
Block a user