Add new refresh status/request button to timeline page

codemagic-setup
Hank Grabowski 2023-01-29 10:14:34 -05:00
rodzic 90574a83d7
commit 1c6a712c15
5 zmienionych plików z 81 dodań i 51 usunięć

Wyświetl plik

@ -20,40 +20,35 @@ class TimelinePanel extends StatelessWidget {
return Center(child: Text('Error getting timeline: ${result.error}'));
}
final items = result.value;
return RefreshIndicator(
onRefresh: () async {
await manager.updateTimeline(timeline, TimelineRefreshType.refresh);
},
child: ListView.separated(
itemBuilder: (context, index) {
if (index == 0) {
return TextButton(
onPressed: () async => await manager.updateTimeline(
timeline, TimelineRefreshType.loadNewer),
child: const Text('Load newer posts'));
}
return ListView.separated(
itemBuilder: (context, index) {
if (index == 0) {
return TextButton(
onPressed: () async => await manager.updateTimeline(
timeline, TimelineRefreshType.loadNewer),
child: const Text('Load newer posts'));
}
if (index == items.length + 1) {
return TextButton(
onPressed: () async => await manager.updateTimeline(
timeline, TimelineRefreshType.loadOlder),
child: const Text('Load older posts'));
}
final itemIndex = index - 1;
final item = items[itemIndex];
_logger.finest(
'Building item: $itemIndex: ${item.entry.toShortString()}');
return PostControl(
originalItem: item,
scrollToId: item.id,
openRemote: false,
showStatusOpenButton: true,
isRoot: false,
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: items.length + 2,
),
if (index == items.length + 1) {
return TextButton(
onPressed: () async => await manager.updateTimeline(
timeline, TimelineRefreshType.loadOlder),
child: const Text('Load older posts'));
}
final itemIndex = index - 1;
final item = items[itemIndex];
_logger
.finest('Building item: $itemIndex: ${item.entry.toShortString()}');
return PostControl(
originalItem: item,
scrollToId: item.id,
openRemote: false,
showStatusOpenButton: true,
isRoot: false,
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: items.length + 2,
);
}
}

Wyświetl plik

@ -243,21 +243,25 @@ class FriendicaClient {
FutureResult<List<TimelineEntry>, ExecError> getUserTimeline(
{String userId = '', int page = 1, int count = 10}) async {
_logger.finest(() => 'Getting user timeline for $userId');
_networkStatusService.startTimelineLoading();
final baseUrl = 'https://$serverName/api/statuses/user_timeline?';
final pagingData = 'count=$count&page=$page';
final url = userId.isEmpty
? '$baseUrl$pagingData'
: '${baseUrl}screen_name=$userId$pagingData';
final request = Uri.parse(url);
return (await _getApiListRequest(request).andThenSuccessAsync(
final result = (await _getApiListRequest(request).andThenSuccessAsync(
(postsJson) async => postsJson.data
.map((json) => TimelineEntryMastodonExtensions.fromJson(json))
.toList()))
.mapError((error) => error as ExecError);
.execErrorCast();
_networkStatusService.finishTimelineLoading();
return result;
}
FutureResult<List<TimelineEntry>, ExecError> getTimeline(
{required TimelineIdentifiers type, required PagingData page}) async {
_networkStatusService.startTimelineLoading();
final String timelinePath = _typeToTimelinePath(type);
final String timelineQPs = _typeToTimelineQueryParameters(type);
final baseUrl = 'https://$serverName/api/v1/$timelinePath';
@ -265,11 +269,13 @@ class FriendicaClient {
'$baseUrl?exclude_replies=true&${page.toQueryParameters()}&$timelineQPs';
final request = Uri.parse(url);
_logger.finest(() => 'Getting ${type.toHumanKey()} with paging data $page');
return (await _getApiListRequest(request).andThenSuccessAsync(
final result = (await _getApiListRequest(request).andThenSuccessAsync(
(postsJson) async => postsJson.data
.map((json) => TimelineEntryMastodonExtensions.fromJson(json))
.toList()))
.execErrorCast();
_networkStatusService.finishTimelineLoading();
return result;
}
FutureResult<Uint8List, ExecError> getFileBytes(Uri url) async {

Wyświetl plik

@ -6,8 +6,10 @@ import 'package:provider/provider.dart';
import '../controls/app_bottom_nav_bar.dart';
import '../controls/padding.dart';
import '../controls/timeline/timeline_panel.dart';
import '../globals.dart';
import '../models/TimelineIdentifiers.dart';
import '../models/group_data.dart';
import '../services/network_status_service.dart';
import '../services/timeline_manager.dart';
class HomeScreen extends StatefulWidget {
@ -34,11 +36,13 @@ class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
_logger.finest('Build');
final groups = context
.watch<TimelineManager>()
.getGroups()
.getValueOrElse(() => [])
.toList();
final nss = getIt<NetworkStatusService>();
final manager = context.watch<TimelineManager>();
final groups = manager.getGroups().getValueOrElse(() => []).toList();
final currentTimeline = TimelineIdentifiers(
timeline: currentType,
auxData: currentGroup?.id ?? '',
);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).canvasColor,
@ -76,6 +80,30 @@ class _HomeScreenState extends State<HomeScreen> {
],
),
actions: [
ValueListenableBuilder(
valueListenable: nss.timelineLoadingStatus,
builder: (context2, executing, _) {
if (executing) {
final theme = Theme.of(context);
final size = theme.appBarTheme.actionsIconTheme?.size ??
theme.iconTheme.size ??
24;
return Center(
child: SizedBox(
width: size,
height: size,
child: CircularProgressIndicator(),
),
);
}
return IconButton(
onPressed: () async => await manager.updateTimeline(
currentTimeline, TimelineRefreshType.refresh),
icon: Icon(
Icons.refresh,
color: Theme.of(context).textTheme.bodyText1!.color,
));
}),
IconButton(
onPressed: () {
context.push('/post/new');
@ -91,10 +119,7 @@ class _HomeScreenState extends State<HomeScreen> {
children: [
Expanded(
child: TimelinePanel(
timeline: TimelineIdentifiers(
timeline: currentType,
auxData: currentGroup?.id ?? '',
),
timeline: currentTimeline,
)),
],
),

Wyświetl plik

@ -1,18 +1,22 @@
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
class NetworkStatusService {
static final _logger = Logger('$NetworkStatusService');
final notificationsUpdateStatus = ValueNotifier<bool>(false);
final timelineLoadingStatus = ValueNotifier<bool>(false);
void startNotificationUpdate() {
_logger.info('Setting Notification Update status to true');
notificationsUpdateStatus.value = true;
}
void finishNotificationUpdate() {
_logger.info('Setting Notification Update status to false');
notificationsUpdateStatus.value = false;
}
void startTimelineLoading() {
timelineLoadingStatus.value = true;
}
void finishTimelineLoading() {
timelineLoadingStatus.value = false;
}
}

Wyświetl plik

@ -8,7 +8,7 @@ import Foundation
import desktop_window
import flutter_secure_storage_macos
import objectbox_flutter_libs
import path_provider_macos
import path_provider_foundation
import shared_preferences_foundation
import sqflite
import url_launcher_macos