Compare commits

...

10 Commits

Author SHA1 Message Date
62ff1c2f1c 🚀 Launch 1.2.1+4 2024-08-04 18:14:28 +08:00
a157596a2e Optimize and fixes 2024-08-04 18:13:59 +08:00
12102bf527 Limit content and read more in posts 2024-08-04 17:39:22 +08:00
c00a018380 🐛 Fix draft box 2024-08-04 17:15:56 +08:00
53b3cac4ca Show hint when dismissible error 2024-08-04 16:26:05 +08:00
19eabfaba1 🚀 Launch 1.2.1+2 2024-08-04 13:27:14 +08:00
ec2eadad6d 🐛 Fix bootstrapper icon issue 2024-08-04 12:59:13 +08:00
54e176e75d 🐛 Fix post editor cannot reply either repost 2024-08-04 12:55:05 +08:00
0a7ccaeefa 🐛 Fix attachment editor title overflow 2024-08-04 12:23:39 +08:00
a5f093e185 🐛 Fix unauthorized wont load stickers 2024-08-04 11:10:25 +08:00
20 changed files with 322 additions and 133 deletions

View File

@ -112,14 +112,15 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
label: 'bsPreparingData',
action: () async {
final AuthProvider auth = Get.find();
if (auth.isAuthorized.isTrue) {
await Future.wait([
Get.find<RealmProvider>().refreshAvailableRealms(),
await Future.wait([
Get.find<StickerProvider>().refreshAvailableStickers(),
if (auth.isAuthorized.isTrue)
Get.find<ChannelProvider>().refreshAvailableChannel(),
if (auth.isAuthorized.isTrue)
Get.find<RelationshipProvider>().refreshRelativeList(),
Get.find<StickerProvider>().refreshAvailableStickers(),
]);
}
if (auth.isAuthorized.isTrue)
Get.find<RealmProvider>().refreshAvailableRealms(),
]);
},
),
(
@ -162,28 +163,29 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
@override
Widget build(BuildContext context) {
if (_isBusy || _isErrored) {
return Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 280,
child: Align(
alignment: Alignment.bottomCenter,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: Image.asset('assets/logo.png', width: 80, height: 80),
return GestureDetector(
child: Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 280,
child: Align(
alignment: Alignment.bottomCenter,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child:
Image.asset('assets/logo.png', width: 80, height: 80),
),
),
),
),
GestureDetector(
child: Column(
Column(
children: [
if (_isErrored && !_isDismissable && !_isBusy)
const Icon(Icons.cancel, size: 24),
if (_isErrored && _isDismissable)
if (_isErrored && _isDismissable && !_isBusy)
const Icon(Icons.warning, size: 24),
if ((_isErrored && _isDismissable && _isBusy) || _isBusy)
const SizedBox(
@ -214,6 +216,15 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
color: _unFocusColor,
),
).paddingOnly(bottom: 4),
if (!_isBusy && _isErrored && _isDismissable)
Text(
'bsDismissibleErrorHint'.tr,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: _unFocusColor,
),
).paddingOnly(bottom: 5),
Text(
'2024 © Solsynth LLC',
textAlign: TextAlign.center,
@ -227,25 +238,25 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
),
],
),
onTap: () {
if (_isBusy) return;
if (_isDismissable) {
setState(() {
_isBusy = false;
_isErrored = false;
});
} else {
setState(() {
_isBusy = true;
_isErrored = false;
_periodCursor = 0;
});
_runPeriods();
}
},
)
],
],
),
),
onTap: () {
if (_isBusy) return;
if (_isDismissable) {
setState(() {
_isBusy = false;
_isErrored = false;
});
} else {
setState(() {
_isBusy = true;
_isErrored = false;
_periodCursor = 0;
});
_runPeriods();
}
},
);
}

View File

@ -104,7 +104,6 @@ abstract class AppRouter {
reply: arguments?.reply,
repost: arguments?.repost,
realm: arguments?.realm,
postListController: arguments?.postListController,
mode: int.tryParse(state.uri.queryParameters['mode'] ?? '0') ?? 0,
),
transitionsBuilder:

View File

@ -300,6 +300,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
PostWarpedListWidget(
isPinned: false,
controller: _postController.pagingController,
onUpdate: () => _postController.reloadAllOver(),
),
]),
),

View File

@ -76,6 +76,8 @@ class _DraftBoxScreenState extends State<DraftBoxScreen> {
itemBuilder: (context, item, index) {
return PostOwnedListEntry(
item: item,
backgroundColor:
Theme.of(context).colorScheme.surfaceContainerLow,
onTap: () async {
showModalBottomSheet(
useRootNavigator: true,
@ -85,7 +87,13 @@ class _DraftBoxScreenState extends State<DraftBoxScreen> {
noReact: true,
),
).then((value) {
if (value != null) _pagingController.refresh();
if (value is Future) {
value.then((_) {
_pagingController.refresh();
});
} else if (value != null) {
_pagingController.refresh();
}
});
},
).paddingOnly(left: 12, right: 12, bottom: 4);

View File

@ -77,7 +77,10 @@ class _FeedSearchScreenState extends State<FeedSearchScreen> {
onRefresh: () => Future.sync(() => _pagingController.refresh()),
child: CustomScrollView(
slivers: [
PostWarpedListWidget(controller: _pagingController),
PostWarpedListWidget(
controller: _pagingController,
onUpdate: () => _pagingController.refresh(),
),
],
),
),

View File

@ -4,7 +4,6 @@ import 'package:solian/controllers/post_list_controller.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/router.dart';
import 'package:solian/screens/account/notification.dart';
import 'package:solian/screens/posts/post_editor.dart';
import 'package:solian/theme.dart';
import 'package:solian/widgets/app_bar_title.dart';
import 'package:solian/widgets/current_state_action.dart';
@ -47,15 +46,20 @@ class _HomeScreenState extends State<HomeScreen>
child: Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
onPressed: () async {
final value = await showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
context: context,
builder: (context) => PostCreatePopup(
controller: _postController,
),
builder: (context) => const PostCreatePopup(),
);
if (value is Future) {
value.then((_) {
_postController.reloadAllOver();
});
} else if (value != null) {
_postController.reloadAllOver();
}
},
),
body: NestedScrollView(
@ -100,6 +104,7 @@ class _HomeScreenState extends State<HomeScreen>
child: CustomScrollView(slivers: [
PostWarpedListWidget(
controller: _postController.pagingController,
onUpdate: () => _postController.reloadAllOver(),
),
]),
),
@ -121,12 +126,10 @@ class _HomeScreenState extends State<HomeScreen>
class PostCreatePopup extends StatelessWidget {
final bool hideDraftBox;
final PostListController controller;
const PostCreatePopup({
super.key,
this.hideDraftBox = false,
required this.controller,
});
@override
@ -142,13 +145,14 @@ class PostCreatePopup extends StatelessWidget {
icon: const Icon(Icons.post_add),
label: 'postEditorModeStory'.tr,
onTap: () {
Navigator.pop(context);
AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(postListController: controller),
queryParameters: {
'mode': 0.toString(),
},
Navigator.pop(
context,
AppRouter.instance.pushNamed(
'postEditor',
queryParameters: {
'mode': 0.toString(),
},
),
);
},
),
@ -156,13 +160,14 @@ class PostCreatePopup extends StatelessWidget {
icon: const Icon(Icons.description),
label: 'postEditorModeArticle'.tr,
onTap: () {
Navigator.pop(context);
AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(postListController: controller),
queryParameters: {
'mode': 1.toString(),
},
Navigator.pop(
context,
AppRouter.instance.pushNamed(
'postEditor',
queryParameters: {
'mode': 1.toString(),
},
),
);
},
),
@ -170,8 +175,10 @@ class PostCreatePopup extends StatelessWidget {
icon: const Icon(Icons.drafts),
label: 'draftBoxOpen'.tr,
onTap: () {
Navigator.pop(context);
AppRouter.instance.pushNamed('draftBox');
Navigator.pop(
context,
AppRouter.instance.pushNamed('draftBox'),
);
},
),
];

View File

@ -61,6 +61,7 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
item: item!,
isClickable: true,
isFullDate: true,
isFullContent: true,
isShowReply: false,
isContentSelectable: true,
),

View File

@ -5,7 +5,6 @@ import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:markdown_toolbar/markdown_toolbar.dart';
import 'package:solian/controllers/post_editor_controller.dart';
import 'package:solian/controllers/post_list_controller.dart';
import 'package:solian/exts.dart';
import 'package:solian/models/post.dart';
import 'package:solian/models/realm.dart';
@ -23,14 +22,12 @@ class PostPublishArguments {
final Post? reply;
final Post? repost;
final Realm? realm;
final PostListController? postListController;
PostPublishArguments({
this.edit,
this.reply,
this.repost,
this.realm,
this.postListController,
});
}
@ -39,7 +36,6 @@ class PostPublishScreen extends StatefulWidget {
final Post? reply;
final Post? repost;
final Realm? realm;
final PostListController? postListController;
final int mode;
const PostPublishScreen({
@ -48,7 +44,6 @@ class PostPublishScreen extends StatefulWidget {
this.reply,
this.repost,
this.realm,
this.postListController,
required this.mode,
});
@ -95,9 +90,6 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
context.showErrorDialog(resp.bodyString);
} else {
_editorController.localClear();
if (widget.postListController != null) {
widget.postListController!.reloadAllOver();
}
AppRouter.instance.pop(resp.body);
}
@ -128,7 +120,15 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
@override
void initState() {
super.initState();
if (widget.edit == null) _editorController.localRead();
if (widget.edit == null && widget.reply == null && widget.repost == null) {
_editorController.localRead();
}
if (widget.reply != null) {
_editorController.replyTo.value = widget.reply;
}
if (widget.repost != null) {
_editorController.repostTo.value = widget.repost;
}
_editorController.contentController.addListener(() => setState(() {}));
_syncWidget();
}
@ -219,10 +219,15 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
collapsedBackgroundColor:
Theme.of(context).colorScheme.surfaceContainer,
children: [
PostItem(
item: _replyTo!,
isReactable: false,
).paddingOnly(bottom: 8),
Container(
constraints: const BoxConstraints(maxHeight: 280),
child: SingleChildScrollView(
child: PostItem(
item: _replyTo!,
isReactable: false,
).paddingOnly(bottom: 8),
),
),
],
),
if (_repostTo != null)
@ -237,10 +242,15 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
collapsedBackgroundColor:
Theme.of(context).colorScheme.surfaceContainer,
children: [
PostItem(
item: _repostTo!,
isReactable: false,
).paddingOnly(bottom: 8),
Container(
constraints: const BoxConstraints(maxHeight: 280),
child: SingleChildScrollView(
child: PostItem(
item: _repostTo!,
isReactable: false,
).paddingOnly(bottom: 8),
),
),
],
),
Expanded(

View File

@ -333,6 +333,7 @@ const i18nEnglish = {
'bsEstablishingConn': 'Establishing Connection',
'bsPreparingData': 'Preparing User Data',
'bsRegisteringPushNotify': 'Enabling Push Notifications',
'bsDismissibleErrorHint': 'Click anywhere to ignore this error',
'postShareContent':
'@content\n\n@username on the Solar Network\nCheck it out: @link',
'postShareSubject': '@username posted a post on the Solar Network',
@ -360,4 +361,5 @@ const i18nEnglish = {
'stickerUploaderName': 'Name',
'stickerUploaderNameHint':
'A human-friendly name given to the user in the sticker selection interface.',
'readMore': 'Read more',
};

View File

@ -306,6 +306,7 @@ const i18nSimplifiedChinese = {
'bsEstablishingConn': '部署连接中',
'bsPreparingData': '正在准备用户资料',
'bsRegisteringPushNotify': '正在启用推送通知',
'bsDismissibleErrorHint': '点击任意地方忽略此错误',
'postShareContent': '@content\n\n@username 在 Solar Network\n原帖地址:@link',
'postShareSubject': '@username 在 Solar Network 上发布了一篇帖子',
'themeColor': '全局主题色',
@ -328,4 +329,5 @@ const i18nSimplifiedChinese = {
'stickerUploaderAliasHint': '将会在输入时使用和贴图包前缀组成占位符。',
'stickerUploaderName': '贴图名称',
'stickerUploaderNameHint': '在贴图选择界面提供给用户的人类友好名称。',
'readMore': '阅读更多',
};

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/exts.dart';
import 'package:solian/models/account.dart';
import 'package:solian/providers/account_status.dart';
import 'package:solian/router.dart';
@ -18,23 +17,38 @@ class AccountProfilePopup extends StatefulWidget {
class _AccountProfilePopupState extends State<AccountProfilePopup> {
bool _isBusy = true;
dynamic _hasError;
Account? _userinfo;
void _getUserinfo() async {
setState(() => _isBusy = true);
final client = ServiceFinder.configureClient('auth');
final resp = await client.get('/users/${widget.name}');
if (resp.statusCode == 200) {
_userinfo = Account.fromJson(resp.body);
setState(() => _isBusy = false);
} else {
context.showErrorDialog(resp.bodyString);
Navigator.pop(context);
try {
final client = ServiceFinder.configureClient('auth');
final resp = await client.get('/users/${widget.name}');
if (resp.statusCode == 200) {
setState(() {
_userinfo = Account.fromJson(resp.body);
_isBusy = false;
});
} else {
setState(() {
_hasError = resp.bodyString;
_isBusy = false;
});
}
} catch (e) {
setState(() {
_hasError = e;
_isBusy = false;
});
}
}
Color get _unFocusColor =>
Theme.of(context).colorScheme.onSurface.withOpacity(0.75);
@override
void initState() {
super.initState();
@ -43,13 +57,35 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
@override
Widget build(BuildContext context) {
if (_isBusy || _userinfo == null) {
if (_isBusy) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.75,
child: const Center(child: CircularProgressIndicator()),
);
}
if (_hasError != null) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.75,
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.cancel, size: 24),
const SizedBox(height: 12),
Text(
_hasError.toString(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: _unFocusColor,
),
),
],
),
);
}
return SizedBox(
height: MediaQuery.of(context).size.height * 0.75,
child: Column(

View File

@ -385,7 +385,9 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
icon: const Icon(Icons.warning),
onPressed: () {},
),
if (!element.isCompleted && element.error == null && canBeCrop)
if (!element.isCompleted &&
element.error == null &&
canBeCrop)
Obx(
() => IconButton(
color: Colors.teal,
@ -398,7 +400,9 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
},
),
),
if (!element.isCompleted && !element.isUploading && element.error == null)
if (!element.isCompleted &&
!element.isUploading &&
element.error == null)
Obx(
() => IconButton(
color: Colors.green,
@ -592,9 +596,13 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'attachmentAdd'.tr,
style: Theme.of(context).textTheme.headlineSmall,
Expanded(
child: Text(
'attachmentAdd'.tr,
style: Theme.of(context).textTheme.headlineSmall,
maxLines: 2,
overflow: TextOverflow.fade,
),
),
const SizedBox(width: 10),
Obx(() {

View File

@ -97,13 +97,13 @@ class _PostActionState extends State<PostAction> {
leading: const FaIcon(FontAwesomeIcons.reply, size: 20),
title: Text('reply'.tr),
onTap: () async {
final value = await AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(reply: widget.item),
Navigator.pop(
context,
AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(reply: widget.item),
),
);
if (value != null) {
Navigator.pop(context, true);
}
},
),
if (!widget.noReact)
@ -112,13 +112,13 @@ class _PostActionState extends State<PostAction> {
leading: const FaIcon(FontAwesomeIcons.retweet, size: 20),
title: Text('repost'.tr),
onTap: () async {
final value = await AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(repost: widget.item),
Navigator.pop(
context,
AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(repost: widget.item),
),
);
if (value != null) {
Navigator.pop(context, true);
}
},
),
if (_canModifyContent && !widget.noReact)
@ -146,13 +146,13 @@ class _PostActionState extends State<PostAction> {
leading: const Icon(Icons.edit),
title: Text('edit'.tr),
onTap: () async {
final value = await AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(edit: widget.item),
Navigator.pop(
context,
AppRouter.instance.pushNamed(
'postEditor',
extra: PostPublishArguments(edit: widget.item),
),
);
if (value != null) {
Navigator.pop(context, true);
}
},
),
if (_canModifyContent)

View File

@ -1,5 +1,6 @@
import 'package:animations/animations.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get_utils/get_utils.dart';
import 'package:intl/intl.dart';
@ -23,6 +24,7 @@ class PostItem extends StatefulWidget {
final bool isShowReply;
final bool isShowEmbed;
final bool isFullDate;
final bool isFullContent;
final bool isContentSelectable;
final String? attachmentParent;
final Color? backgroundColor;
@ -36,6 +38,7 @@ class PostItem extends StatefulWidget {
this.isShowReply = true,
this.isShowEmbed = true,
this.isFullDate = false,
this.isFullContent = false,
this.isContentSelectable = false,
this.attachmentParent,
this.backgroundColor,
@ -164,6 +167,7 @@ class _PostItemState extends State<PostItem> {
Widget _buildReply(BuildContext context) {
return OpenContainer(
tappable: widget.isClickable,
closedBuilder: (_, openContainer) => Column(
children: [
Row(
@ -202,13 +206,15 @@ class _PostItemState extends State<PostItem> {
),
closedElevation: 0,
openElevation: 0,
closedColor: widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
closedColor:
widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
openColor: Theme.of(context).colorScheme.surface,
);
}
Widget _buildRepost(BuildContext context) {
return OpenContainer(
tappable: widget.isClickable,
closedBuilder: (_, openContainer) => Column(
children: [
Row(
@ -247,11 +253,14 @@ class _PostItemState extends State<PostItem> {
),
closedElevation: 0,
openElevation: 0,
closedColor: widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
closedColor:
widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
openColor: Theme.of(context).colorScheme.surface,
);
}
double _contentHeight = 0;
@override
Widget build(BuildContext context) {
final List<int> attachments = item.body['attachments'] is List
@ -295,6 +304,7 @@ class _PostItemState extends State<PostItem> {
}
return OpenContainer(
tappable: widget.isClickable,
closedBuilder: (_, openContainer) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -322,11 +332,31 @@ class _PostItemState extends State<PostItem> {
_buildHeader(),
SizedContainer(
maxWidth: 640,
child: MarkdownTextContent(
content: item.body['content'],
isSelectable: widget.isContentSelectable,
).paddingOnly(left: 12, right: 8),
maxHeight: widget.isFullContent ? double.infinity : 320,
child: _MeasureSize(
onChange: (size) {
_contentHeight = size.height;
},
child: MarkdownTextContent(
content: item.body['content'],
isSelectable: widget.isContentSelectable,
).paddingOnly(left: 12, right: 8),
),
),
if (_contentHeight >= 320 &&
widget.isClickable &&
!widget.isFullContent)
InkWell(
child: Text(
'readMore'.tr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
onTap: () {
openContainer();
},
).paddingOnly(left: 12, top: 4),
if (widget.item.replyTo != null && widget.isShowEmbed)
_buildReply(context).paddingOnly(top: 4),
if (widget.item.repostTo != null && widget.isShowEmbed)
@ -377,8 +407,52 @@ class _PostItemState extends State<PostItem> {
),
closedElevation: 0,
openElevation: 0,
closedColor: widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
closedColor:
widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
openColor: Theme.of(context).colorScheme.surface,
);
}
}
typedef _OnWidgetSizeChange = void Function(Size size);
class _MeasureSizeRenderObject extends RenderProxyBox {
Size? oldSize;
_OnWidgetSizeChange onChange;
_MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
Size newSize = child!.size;
if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class _MeasureSize extends SingleChildRenderObjectWidget {
final _OnWidgetSizeChange onChange;
const _MeasureSize({
super.key,
required this.onChange,
required Widget super.child,
});
@override
RenderObject createRenderObject(BuildContext context) {
return _MeasureSizeRenderObject(onChange);
}
@override
void updateRenderObject(
BuildContext context, covariant _MeasureSizeRenderObject renderObject) {
renderObject.onChange = onChange;
}
}

View File

@ -85,7 +85,13 @@ class PostListEntryWidget extends StatelessWidget {
context: context,
builder: (context) => PostAction(item: item),
).then((value) {
if (value != null) onUpdate();
if (value is Future) {
value.then((_) {
onUpdate();
});
} else if (value != null) {
onUpdate();
}
});
},
);

View File

@ -6,18 +6,19 @@ import 'package:solian/widgets/posts/post_item.dart';
class PostOwnedListEntry extends StatelessWidget {
final Post item;
final Function onTap;
final Color? backgroundColor;
const PostOwnedListEntry({
super.key,
required this.item,
required this.onTap,
this.backgroundColor,
});
@override
Widget build(BuildContext context) {
return Card(
child: InkWell(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -28,6 +29,7 @@ class PostOwnedListEntry extends StatelessWidget {
isClickable: false,
isShowReply: false,
isReactable: false,
backgroundColor: backgroundColor,
).paddingSymmetric(vertical: 8),
],
),

View File

@ -9,6 +9,7 @@ class PostWarpedListWidget extends StatelessWidget {
final bool isNestedClickable;
final bool isPinned;
final PagingController<int, Post> controller;
final Function? onUpdate;
const PostWarpedListWidget({
super.key,
@ -17,6 +18,7 @@ class PostWarpedListWidget extends StatelessWidget {
this.isClickable = true,
this.isNestedClickable = true,
this.isPinned = true,
this.onUpdate,
});
@override
@ -35,9 +37,7 @@ class PostWarpedListWidget extends StatelessWidget {
isNestedClickable: isNestedClickable,
isClickable: isClickable,
item: item,
onUpdate: () {
controller.refresh();
},
onUpdate: onUpdate ?? () {},
);
},
),

View File

@ -3,11 +3,13 @@ import 'package:flutter/material.dart';
class SizedContainer extends StatelessWidget {
final Widget child;
final double maxWidth;
final double maxHeight;
const SizedContainer({
super.key,
required this.child,
this.maxWidth = 720,
this.maxHeight = double.infinity,
});
@override
@ -15,7 +17,7 @@ class SizedContainer extends StatelessWidget {
return Align(
alignment: Alignment.centerLeft,
child: Container(
constraints: BoxConstraints(maxWidth: maxWidth),
constraints: BoxConstraints(maxWidth: maxWidth, maxHeight: maxHeight),
child: child,
),
);

View File

@ -385,6 +385,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
field_suggestion:
dependency: "direct main"
description:
name: field_suggestion
sha256: "596362ed67a661a18e01e4f51b8b92424f333baf37cebd48cc647a4c82c858d5"
url: "https://pub.dev"
source: hosted
version: "0.2.5"
file:
dependency: transitive
description:
@ -736,6 +744,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
highlightable:
dependency: transitive
description:
name: highlightable
sha256: "526793e148c91977b694d75d99cd34401ea3b65efd223e7b539c76916af86ffd"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
http:
dependency: transitive
description:

View File

@ -2,7 +2,7 @@ name: solian
description: "The Solar Network App"
publish_to: "none"
version: 1.2.1+1
version: 1.2.1+4
environment:
sdk: ">=3.3.4 <4.0.0"
@ -66,6 +66,7 @@ dependencies:
animations: ^2.0.11
avatar_stack: ^1.2.0
async: ^2.11.0
field_suggestion: ^0.2.5
dev_dependencies:
flutter_test: