♻️ Optimized large screen display post effect

 Push notification
This commit is contained in:
2024-11-21 22:10:12 +08:00
parent 9fd30a1994
commit d41e358c6a
16 changed files with 340 additions and 27 deletions

View File

@ -12,6 +12,7 @@ import 'package:responsive_framework/responsive_framework.dart';
import 'package:surface/firebase_options.dart';
import 'package:surface/providers/channel.dart';
import 'package:surface/providers/navigation.dart';
import 'package:surface/providers/notification.dart';
import 'package:surface/providers/sn_attachment.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/theme.dart';
@ -73,6 +74,7 @@ class SolianApp extends StatelessWidget {
Provider(create: (ctx) => SnAttachmentProvider(ctx)),
Provider(create: (ctx) => UserDirectoryProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => ChatChannelProvider(ctx)),
],

View File

@ -0,0 +1,58 @@
import 'dart:developer';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_udid/flutter_udid.dart';
import 'package:provider/provider.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/userinfo.dart';
import 'package:surface/providers/websocket.dart';
class NotificationProvider extends ChangeNotifier {
late final SnNetworkProvider _sn;
late final UserProvider _ua;
late final WebSocketProvider _ws;
NotificationProvider(BuildContext context) {
_sn = context.read<SnNetworkProvider>();
_ua = context.read<UserProvider>();
_ws = context.read<WebSocketProvider>();
}
Future<void> registerPushNotifications() async {
if (kIsWeb) return;
if (!_ua.isAuthorized) return;
late final String? token;
late final String provider;
var deviceUuid = await FlutterUdid.consistentUdid;
if (deviceUuid.isEmpty) {
log("Unable to active push notifications, couldn't get device uuid");
return;
} else {
log('Device UUID is $deviceUuid');
log('Registering device push notifications...');
}
if (Platform.isIOS || Platform.isMacOS) {
provider = 'apple';
token = await FirebaseMessaging.instance.getAPNSToken();
} else {
provider = 'firebase';
token = await FirebaseMessaging.instance.getToken();
}
log('Device Push Token is $token');
await _sn.client.post(
'/cgi/id/notifications/subscribe',
data: {
'provider': provider,
'device_token': token,
'device_id': deviceUuid,
},
);
}
}

View File

@ -5,7 +5,6 @@ import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/sn_attachment.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/post.dart';
@ -174,10 +173,7 @@ class _ExploreScreenState extends State<ExploreScreen> {
onFetchData: _fetchPosts,
itemBuilder: (context, idx) {
return GestureDetector(
child: Container(
constraints: const BoxConstraints(maxWidth: 640),
child: PostItem(data: _posts[idx]),
).center(),
child: PostItem(data: _posts[idx], maxWidth: 640),
onTap: () {
GoRouter.of(context).pushNamed(
'postDetail',

View File

@ -30,7 +30,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
final nav = context.watch<NavigationProvider>();
final backgroundColor = ResponsiveBreakpoints.of(context).largerThan(MOBILE)
? Theme.of(context).colorScheme.surface
? Colors.transparent
: null;
return ListenableBuilder(
@ -57,7 +57,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
).padding(
horizontal: 32,
top: MediaQuery.of(context).padding.top > 16 ? 8 : 16,
bottom: 16,
bottom: 8,
),
...destinations.where((ele) => ele.isPinned).map((ele) {
return NavigationDrawerDestination(

View File

@ -95,12 +95,10 @@ class PostCommentSliverListState extends State<PostCommentSliverList> {
onFetchData: _fetchPosts,
itemBuilder: (context, idx) {
return GestureDetector(
child: Container(
constraints: BoxConstraints(
maxWidth: widget.maxWidth ?? double.infinity,
),
child: PostItem(data: _posts[idx]),
).center(),
child: PostItem(
data: _posts[idx],
maxWidth: widget.maxWidth,
),
onTap: () {
GoRouter.of(context).pushNamed(
'postDetail',

View File

@ -18,12 +18,14 @@ class PostItem extends StatelessWidget {
final SnPost data;
final bool showReactions;
final bool showComments;
final double? maxWidth;
final Function(SnPost data)? onChanged;
const PostItem({
super.key,
required this.data,
this.showReactions = true,
this.showComments = true,
this.maxWidth,
this.onChanged,
});
@ -34,14 +36,23 @@ class PostItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_PostContentHeader(data: data).padding(horizontal: 12, vertical: 8),
_PostContentBody(data: data.body).padding(horizontal: 16, bottom: 6),
if (data.repostTo != null)
_PostQuoteContent(child: data.repostTo!).padding(
horizontal: 12,
Container(
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
child: Column(
children: [
_PostContentHeader(data: data)
.padding(horizontal: 12, vertical: 8),
_PostContentBody(data: data.body)
.padding(horizontal: 16, bottom: 6),
if (data.repostTo != null)
_PostQuoteContent(child: data.repostTo!).padding(
horizontal: 12,
),
],
),
),
if (data.preload?.attachments?.isNotEmpty ?? true)
AttachmentList(
data: data.preload!.attachments!,
@ -49,12 +60,19 @@ class PostItem extends StatelessWidget {
maxHeight: 520,
listPadding: const EdgeInsets.symmetric(horizontal: 12),
),
_PostBottomAction(
data: data,
showComments: showComments,
showReactions: showReactions,
onChanged: _onChanged,
).padding(left: 12, right: 18),
Container(
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
child: Column(
children: [
_PostBottomAction(
data: data,
showComments: showComments,
showReactions: showReactions,
onChanged: _onChanged,
).padding(left: 12, right: 18),
],
),
),
],
);
}