✨ Extended refresh indicator (keyboard based)
This commit is contained in:
@@ -9,6 +9,7 @@ import 'package:island/widgets/poll/poll_feedback.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';
|
||||
|
||||
part 'poll_list.g.dart';
|
||||
|
||||
@@ -86,7 +87,7 @@ class CreatorPollListScreen extends HookConsumerWidget {
|
||||
onPressed: () => _createPoll(context),
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
body: ExtendedRefreshIndicator(
|
||||
onRefresh: () => ref.refresh(pollListNotifierProvider(pubName).future),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
|
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:island/pods/webfeed.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/empty_state.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
class WebFeedListScreen extends ConsumerWidget {
|
||||
@@ -20,7 +21,10 @@ class WebFeedListScreen extends ConsumerWidget {
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Symbols.add),
|
||||
onPressed: () {
|
||||
context.pushNamed('creatorFeedNew', pathParameters: {'name': pubName});
|
||||
context.pushNamed(
|
||||
'creatorFeedNew',
|
||||
pathParameters: {'name': pubName},
|
||||
);
|
||||
},
|
||||
),
|
||||
body: feedsAsync.when(
|
||||
@@ -32,7 +36,7 @@ class WebFeedListScreen extends ConsumerWidget {
|
||||
description: 'Add a new web feed to get started',
|
||||
);
|
||||
}
|
||||
return RefreshIndicator(
|
||||
return ExtendedRefreshIndicator(
|
||||
onRefresh: () => ref.refresh(webFeedListProvider(pubName).future),
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
@@ -62,7 +66,10 @@ class WebFeedListScreen extends ConsumerWidget {
|
||||
),
|
||||
trailing: const Icon(Symbols.chevron_right),
|
||||
onTap: () {
|
||||
context.pushNamed('creatorFeedEdit', pathParameters: {'name': pubName, 'feedId': feed.id});
|
||||
context.pushNamed(
|
||||
'creatorFeedEdit',
|
||||
pathParameters: {'name': pubName, 'feedId': feed.id},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@@ -9,6 +9,7 @@ import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/response.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
|
||||
part 'bots.g.dart';
|
||||
|
||||
@@ -60,7 +61,7 @@ class BotsScreen extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
return RefreshIndicator(
|
||||
return ExtendedRefreshIndicator(
|
||||
onRefresh:
|
||||
() => ref.refresh(botsProvider(publisherName, projectId).future),
|
||||
child: ListView.builder(
|
||||
|
@@ -27,6 +27,7 @@ import 'package:island/pods/network.dart';
|
||||
import 'package:island/widgets/realm/realm_card.dart';
|
||||
import 'package:island/widgets/publisher/publisher_card.dart';
|
||||
import 'package:island/widgets/web_article_card.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
part 'explore.g.dart';
|
||||
@@ -368,7 +369,7 @@ class ExploreScreen extends HookConsumerWidget {
|
||||
|
||||
final isWide = isWideScreen(context);
|
||||
|
||||
return RefreshIndicator(
|
||||
return ExtendedRefreshIndicator(
|
||||
onRefresh: () => Future.sync(activitiesNotifier.forceRefresh),
|
||||
child: PagingHelperView(
|
||||
provider: activityListNotifierProvider(filter),
|
||||
|
@@ -23,6 +23,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:island/widgets/realm/realm_list_tile.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
|
||||
part 'realms.g.dart';
|
||||
|
||||
@@ -90,7 +91,7 @@ class RealmListScreen extends HookConsumerWidget {
|
||||
},
|
||||
),
|
||||
floatingActionButtonLocation: TabbedFabLocation(context),
|
||||
body: RefreshIndicator(
|
||||
body: ExtendedRefreshIndicator(
|
||||
child: realms.when(
|
||||
data:
|
||||
(value) => Column(
|
||||
|
@@ -12,6 +12,7 @@ import 'package:island/widgets/content/sheet.dart';
|
||||
import 'package:island/widgets/response.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
|
||||
part 'account_devices.g.dart';
|
||||
|
||||
@@ -177,7 +178,7 @@ class AccountSessionSheet extends HookConsumerWidget {
|
||||
titleText: 'authSessions'.tr(),
|
||||
child: authDevices.when(
|
||||
data:
|
||||
(data) => RefreshIndicator(
|
||||
(data) => ExtendedRefreshIndicator(
|
||||
onRefresh:
|
||||
() => Future.sync(() => ref.invalidate(authDevicesProvider)),
|
||||
child: ListView.builder(
|
||||
|
67
lib/widgets/extended_refresh_indicator.dart
Normal file
67
lib/widgets/extended_refresh_indicator.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class RefreshIntent extends Intent {
|
||||
const RefreshIntent();
|
||||
}
|
||||
|
||||
class ExtendedRefreshIndicator extends StatefulWidget {
|
||||
final Widget child;
|
||||
final RefreshCallback onRefresh;
|
||||
|
||||
const ExtendedRefreshIndicator({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.onRefresh,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ExtendedRefreshIndicator> createState() =>
|
||||
_ExtendedRefreshIndicatorState();
|
||||
}
|
||||
|
||||
class _ExtendedRefreshIndicatorState extends State<ExtendedRefreshIndicator> {
|
||||
late final FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_focusNode = FocusNode();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_focusNode.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Shortcuts(
|
||||
shortcuts: <LogicalKeySet, Intent>{
|
||||
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyR):
|
||||
const RefreshIntent(),
|
||||
LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyR):
|
||||
const RefreshIntent(),
|
||||
LogicalKeySet(LogicalKeyboardKey.f5): const RefreshIntent(),
|
||||
},
|
||||
child: Actions(
|
||||
actions: <Type, Action<Intent>>{
|
||||
RefreshIntent: CallbackAction<RefreshIntent>(
|
||||
onInvoke: (RefreshIntent intent) => widget.onRefresh(),
|
||||
),
|
||||
},
|
||||
child: Focus(
|
||||
focusNode: _focusNode,
|
||||
child: RefreshIndicator(
|
||||
onRefresh: widget.onRefresh,
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:flutter_popup_card/flutter_popup_card.dart';
|
||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||
|
||||
part 'picker.g.dart';
|
||||
|
||||
@@ -208,7 +209,7 @@ class _PackSwitcherState extends State<_PackSwitcher> {
|
||||
|
||||
// Content
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
child: ExtendedRefreshIndicator(
|
||||
onRefresh: widget.onRefresh,
|
||||
child: _StickersGrid(
|
||||
pack: selectedPack,
|
||||
|
Reference in New Issue
Block a user