Compare commits
3 Commits
1347aacbc5
...
d7c1ffe3cc
Author | SHA1 | Date | |
---|---|---|---|
d7c1ffe3cc | |||
240ad7dc7e | |||
bb5fe9c380 |
@ -403,6 +403,7 @@
|
|||||||
"accountStatusOffline": "Offline",
|
"accountStatusOffline": "Offline",
|
||||||
"accountStatusLastSeen": "Last seen at {}",
|
"accountStatusLastSeen": "Last seen at {}",
|
||||||
"postArticle": "Article on the Solar Network",
|
"postArticle": "Article on the Solar Network",
|
||||||
|
"postStory": "Story on the Solar Network",
|
||||||
"articleWrittenAt": "Written at {}",
|
"articleWrittenAt": "Written at {}",
|
||||||
"articleEditedAt": "Edited at {}",
|
"articleEditedAt": "Edited at {}",
|
||||||
"attachmentSaved": "Saved to album",
|
"attachmentSaved": "Saved to album",
|
||||||
@ -436,5 +437,9 @@
|
|||||||
"publisherBlockHint": "Block {}",
|
"publisherBlockHint": "Block {}",
|
||||||
"publisherBlockHintDescription": "You are going to block this publisher's maintainer, this will also block publishers that run by the same user.",
|
"publisherBlockHintDescription": "You are going to block this publisher's maintainer, this will also block publishers that run by the same user.",
|
||||||
"userUnblocked": "{} has been unblocked.",
|
"userUnblocked": "{} has been unblocked.",
|
||||||
"userBlocked": "{} has been blocked."
|
"userBlocked": "{} has been blocked.",
|
||||||
|
"postSharingViaPicture": "Capturing post as picture, please stand by...",
|
||||||
|
"postImageShareAds": "Explore posts on the Solar Network",
|
||||||
|
"postShare": "Share",
|
||||||
|
"postShareImage": "Share via Image"
|
||||||
}
|
}
|
||||||
|
@ -401,6 +401,7 @@
|
|||||||
"accountStatusOffline": "离线",
|
"accountStatusOffline": "离线",
|
||||||
"accountStatusLastSeen": "最后一次在 {} 上线",
|
"accountStatusLastSeen": "最后一次在 {} 上线",
|
||||||
"postArticle": "Solar Network 上的文章",
|
"postArticle": "Solar Network 上的文章",
|
||||||
|
"postStory": "Solar Network 上的故事",
|
||||||
"articleWrittenAt": "发表于 {}",
|
"articleWrittenAt": "发表于 {}",
|
||||||
"articleEditedAt": "编辑于 {}",
|
"articleEditedAt": "编辑于 {}",
|
||||||
"attachmentSaved": "已保存到相册",
|
"attachmentSaved": "已保存到相册",
|
||||||
@ -434,5 +435,9 @@
|
|||||||
"publisherBlockHint": "屏蔽 {}",
|
"publisherBlockHint": "屏蔽 {}",
|
||||||
"publisherBlockHintDescription": "你正要屏蔽此发布者的运营者,该操作也将屏蔽由同一用户运营的发布者。",
|
"publisherBlockHintDescription": "你正要屏蔽此发布者的运营者,该操作也将屏蔽由同一用户运营的发布者。",
|
||||||
"userUnblocked": "已解除屏蔽用户 {}",
|
"userUnblocked": "已解除屏蔽用户 {}",
|
||||||
"userBlocked": "已屏蔽用户 {}"
|
"userBlocked": "已屏蔽用户 {}",
|
||||||
|
"postSharingViaPicture": "正在生成帖子截图,请稍等片刻……",
|
||||||
|
"postImageShareAds": "来 Solar Network 探索更多有趣帖子",
|
||||||
|
"postShare": "分享",
|
||||||
|
"postShareImage": "分享帖图"
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- croppy (0.0.1):
|
- croppy (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- cupertino_http (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- DKImagePickerController/Core (4.3.9):
|
- DKImagePickerController/Core (4.3.9):
|
||||||
@ -196,11 +194,6 @@ PODS:
|
|||||||
- SDWebImage (5.20.0):
|
- SDWebImage (5.20.0):
|
||||||
- SDWebImage/Core (= 5.20.0)
|
- SDWebImage/Core (= 5.20.0)
|
||||||
- SDWebImage/Core (5.20.0)
|
- SDWebImage/Core (5.20.0)
|
||||||
- Sentry/HybridSDK (8.41.0)
|
|
||||||
- sentry_flutter (8.11.0):
|
|
||||||
- Flutter
|
|
||||||
- FlutterMacOS
|
|
||||||
- Sentry/HybridSDK (= 8.41.0)
|
|
||||||
- share_plus (0.0.1):
|
- share_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
@ -221,7 +214,6 @@ PODS:
|
|||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
||||||
- croppy (from `.symlinks/plugins/croppy/ios`)
|
- croppy (from `.symlinks/plugins/croppy/ios`)
|
||||||
- cupertino_http (from `.symlinks/plugins/cupertino_http/ios`)
|
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
||||||
@ -242,7 +234,6 @@ DEPENDENCIES:
|
|||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
||||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
@ -267,7 +258,6 @@ SPEC REPOS:
|
|||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
- Sentry
|
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
- WebRTC-SDK
|
- WebRTC-SDK
|
||||||
|
|
||||||
@ -276,8 +266,6 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/connectivity_plus/darwin"
|
:path: ".symlinks/plugins/connectivity_plus/darwin"
|
||||||
croppy:
|
croppy:
|
||||||
:path: ".symlinks/plugins/croppy/ios"
|
:path: ".symlinks/plugins/croppy/ios"
|
||||||
cupertino_http:
|
|
||||||
:path: ".symlinks/plugins/cupertino_http/ios"
|
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
file_picker:
|
file_picker:
|
||||||
@ -318,8 +306,6 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
screen_brightness_ios:
|
screen_brightness_ios:
|
||||||
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
||||||
sentry_flutter:
|
|
||||||
:path: ".symlinks/plugins/sentry_flutter/ios"
|
|
||||||
share_plus:
|
share_plus:
|
||||||
:path: ".symlinks/plugins/share_plus/ios"
|
:path: ".symlinks/plugins/share_plus/ios"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
@ -336,7 +322,6 @@ EXTERNAL SOURCES:
|
|||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
connectivity_plus: 4c41c08fc6d7c91f63bc7aec70ffe3730b04f563
|
connectivity_plus: 4c41c08fc6d7c91f63bc7aec70ffe3730b04f563
|
||||||
croppy: b6199bc8d56bd2e03cc11609d1c47ad9875c1321
|
croppy: b6199bc8d56bd2e03cc11609d1c47ad9875c1321
|
||||||
cupertino_http: 1a3a0f163c1b26e7f1a293b33d476e0fde7a64ec
|
|
||||||
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
|
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
|
||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
@ -372,8 +357,6 @@ SPEC CHECKSUMS:
|
|||||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
||||||
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
||||||
Sentry: 54d0fe6c0df448497c8ed4cce66ccf7027e1823e
|
|
||||||
sentry_flutter: 83a84efb7f978522c9127fbc0c07dab09663eecc
|
|
||||||
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||||
|
@ -53,6 +53,11 @@ class SnPostContentProvider {
|
|||||||
if (out.body['thumbnail'] != null) {
|
if (out.body['thumbnail'] != null) {
|
||||||
rids.add(out.body['thumbnail']);
|
rids.add(out.body['thumbnail']);
|
||||||
}
|
}
|
||||||
|
if (out.repostId != null) {
|
||||||
|
out = out.copyWith(
|
||||||
|
repostTo: await _preloadRelatedDataSingle(out.repostTo!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final attachments = await _attach.getMultiple(rids.toList());
|
final attachments = await _attach.getMultiple(rids.toList());
|
||||||
out = out.copyWith(
|
out = out.copyWith(
|
||||||
|
@ -2,7 +2,6 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -238,7 +238,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
text: _account!.nick,
|
text: _account!.nick,
|
||||||
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
||||||
color: Colors.white,
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -246,7 +246,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
text: '@${_account!.name}',
|
text: '@${_account!.name}',
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
color: Colors.white,
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -84,12 +84,16 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
|
|||||||
text: TextSpan(children: [
|
text: TextSpan(children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: _data?.body['title'] ?? 'postNoun'.tr(),
|
text: _data?.body['title'] ?? 'postNoun'.tr(),
|
||||||
style: Theme.of(context).textTheme.titleLarge!.copyWith(color: Colors.white),
|
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const TextSpan(text: '\n'),
|
const TextSpan(text: '\n'),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: 'postDetail'.tr(),
|
text: 'postDetail'.tr(),
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.white),
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
|
@ -149,12 +149,16 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
text: TextSpan(children: [
|
text: TextSpan(children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: _writeController.title.isNotEmpty ? _writeController.title : 'untitled'.tr(),
|
text: _writeController.title.isNotEmpty ? _writeController.title : 'untitled'.tr(),
|
||||||
style: Theme.of(context).textTheme.titleLarge!.copyWith(color: Colors.white),
|
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const TextSpan(text: '\n'),
|
const TextSpan(text: '\n'),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: PostWriteController.kTitleMap[widget.mode]!.tr(),
|
text: PostWriteController.kTitleMap[widget.mode]!.tr(),
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.white),
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
@ -201,7 +201,6 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> with SingleTi
|
|||||||
setState(() => _isWorking = true);
|
setState(() => _isWorking = true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
|
||||||
final rel = context.read<SnRelationshipProvider>();
|
final rel = context.read<SnRelationshipProvider>();
|
||||||
await rel.updateRelationship(_account!.id, 1, _accountRelationship?.permNodes ?? {});
|
await rel.updateRelationship(_account!.id, 1, _accountRelationship?.permNodes ?? {});
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
@ -288,7 +287,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> with SingleTi
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
text: _publisher!.nick,
|
text: _publisher!.nick,
|
||||||
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
style: Theme.of(context).textTheme.titleLarge!.copyWith(
|
||||||
color: Colors.white,
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dismissible_page/dismissible_page.dart';
|
import 'package:dismissible_page/dismissible_page.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -14,19 +15,21 @@ class AttachmentList extends StatefulWidget {
|
|||||||
final List<SnAttachment?> data;
|
final List<SnAttachment?> data;
|
||||||
final bool bordered;
|
final bool bordered;
|
||||||
final bool noGrow;
|
final bool noGrow;
|
||||||
|
final bool isFlatted;
|
||||||
final double? maxHeight;
|
final double? maxHeight;
|
||||||
final EdgeInsets? listPadding;
|
final EdgeInsets? listPadding;
|
||||||
|
|
||||||
const AttachmentList({
|
const AttachmentList({
|
||||||
super.key,
|
super.key,
|
||||||
required this.data,
|
required this.data,
|
||||||
this.bordered = false,
|
this.bordered = false,
|
||||||
this.noGrow = false,
|
this.noGrow = false,
|
||||||
|
this.isFlatted = false,
|
||||||
this.maxHeight,
|
this.maxHeight,
|
||||||
this.listPadding,
|
this.listPadding,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const BorderRadius kDefaultRadius =
|
static const BorderRadius kDefaultRadius = BorderRadius.all(Radius.circular(8));
|
||||||
BorderRadius.all(Radius.circular(8));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AttachmentList> createState() => _AttachmentListState();
|
State<AttachmentList> createState() => _AttachmentListState();
|
||||||
@ -44,9 +47,8 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, layoutConstraints) {
|
builder: (context, layoutConstraints) {
|
||||||
final borderSide = widget.bordered
|
final borderSide =
|
||||||
? BorderSide(width: 1, color: Theme.of(context).dividerColor)
|
widget.bordered ? BorderSide(width: 1, color: Theme.of(context).dividerColor) : BorderSide.none;
|
||||||
: BorderSide.none;
|
|
||||||
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
|
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
|
||||||
final constraints = BoxConstraints(
|
final constraints = BoxConstraints(
|
||||||
minWidth: 80,
|
minWidth: 80,
|
||||||
@ -56,14 +58,13 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
|
|
||||||
if (widget.data.isEmpty) return const SizedBox.shrink();
|
if (widget.data.isEmpty) return const SizedBox.shrink();
|
||||||
if (widget.data.length == 1) {
|
if (widget.data.length == 1) {
|
||||||
final singleAspectRatio =
|
final singleAspectRatio = widget.data[0]?.metadata['ratio']?.toDouble() ??
|
||||||
widget.data[0]?.metadata['ratio']?.toDouble() ??
|
switch (widget.data[0]?.mimetype.split('/').firstOrNull) {
|
||||||
switch (widget.data[0]?.mimetype.split('/').firstOrNull) {
|
'audio' => 16 / 9,
|
||||||
'audio' => 16 / 9,
|
'video' => 16 / 9,
|
||||||
'video' => 16 / 9,
|
_ => 1,
|
||||||
_ => 1,
|
}
|
||||||
}
|
.toDouble();
|
||||||
.toDouble();
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
constraints: ResponsiveBreakpoints.of(context).largerThan(MOBILE)
|
constraints: ResponsiveBreakpoints.of(context).largerThan(MOBILE)
|
||||||
@ -79,8 +80,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
if (ResponsiveBreakpoints.of(context).largerThan(MOBILE) ||
|
if (ResponsiveBreakpoints.of(context).largerThan(MOBILE) || widget.noGrow) {
|
||||||
widget.noGrow) {
|
|
||||||
return Padding(
|
return Padding(
|
||||||
// Single child list-like displaying
|
// Single child list-like displaying
|
||||||
padding: widget.listPadding ?? EdgeInsets.zero,
|
padding: widget.listPadding ?? EdgeInsets.zero,
|
||||||
@ -129,6 +129,37 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.isFlatted) {
|
||||||
|
return Wrap(
|
||||||
|
spacing: 4,
|
||||||
|
runSpacing: 4,
|
||||||
|
children: widget.data
|
||||||
|
.mapIndexed(
|
||||||
|
(idx, ele) => AspectRatio(
|
||||||
|
aspectRatio: (ele?.metadata['ratio'] ?? 1).toDouble(),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: backgroundColor,
|
||||||
|
border: Border(
|
||||||
|
top: borderSide,
|
||||||
|
bottom: borderSide,
|
||||||
|
),
|
||||||
|
borderRadius: AttachmentList.kDefaultRadius,
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: AttachmentList.kDefaultRadius,
|
||||||
|
child: AttachmentItem(
|
||||||
|
data: ele,
|
||||||
|
heroTag: heroTags[idx],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return AspectRatio(
|
return AspectRatio(
|
||||||
aspectRatio: (widget.data.firstOrNull?.metadata['ratio'] ?? 1).toDouble(),
|
aspectRatio: (widget.data.firstOrNull?.metadata['ratio'] ?? 1).toDouble(),
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -147,9 +178,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushTransparentRoute(
|
context.pushTransparentRoute(
|
||||||
AttachmentZoomView(
|
AttachmentZoomView(
|
||||||
data: widget.data
|
data: widget.data.where((ele) => ele != null).cast(),
|
||||||
.where((ele) => ele != null)
|
|
||||||
.cast(),
|
|
||||||
initialIndex: idx,
|
initialIndex: idx,
|
||||||
heroTags: heroTags,
|
heroTags: heroTags,
|
||||||
),
|
),
|
||||||
|
@ -5,10 +5,15 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:popover/popover.dart';
|
import 'package:popover/popover.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:relative_time/relative_time.dart';
|
import 'package:relative_time/relative_time.dart';
|
||||||
|
import 'package:responsive_framework/responsive_framework.dart';
|
||||||
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
@ -52,10 +57,66 @@ class PostItem extends StatelessWidget {
|
|||||||
if (onChanged != null) onChanged!(data);
|
if (onChanged != null) onChanged!(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _doShare(BuildContext context) {
|
||||||
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
|
final url = 'https://solsynth.dev/posts/${data.id}';
|
||||||
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||||
|
Share.shareUri(Uri.parse(url), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
|
} else {
|
||||||
|
Share.share(url, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _doShareViaPicture(BuildContext context) async {
|
||||||
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
|
context.showSnackbar('postSharingViaPicture'.tr());
|
||||||
|
|
||||||
|
final controller = ScreenshotController();
|
||||||
|
final capturedImage = await controller.captureFromLongWidget(
|
||||||
|
InheritedTheme.captureAll(
|
||||||
|
context,
|
||||||
|
MediaQuery(
|
||||||
|
data: MediaQuery.of(context),
|
||||||
|
child: Material(
|
||||||
|
child: MultiProvider(
|
||||||
|
providers: [
|
||||||
|
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
||||||
|
],
|
||||||
|
child: ResponsiveBreakpoints.builder(
|
||||||
|
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
||||||
|
child: PostShareImage(data: data),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pixelRatio: 3,
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (kIsWeb) return;
|
||||||
|
|
||||||
|
final directory = await getTemporaryDirectory();
|
||||||
|
final imagePath = await File(
|
||||||
|
'${directory.path}/sn-share-via-image-${DateTime.now().millisecondsSinceEpoch}.png',
|
||||||
|
).create();
|
||||||
|
await imagePath.writeAsBytes(capturedImage);
|
||||||
|
|
||||||
|
await Share.shareXFiles(
|
||||||
|
[XFile(imagePath.path)],
|
||||||
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
await imagePath.delete();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
|
final ua = context.read<UserProvider>();
|
||||||
|
final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user!.id;
|
||||||
|
|
||||||
// Article headline preview
|
// Article headline preview
|
||||||
if (!showFullPost && data.type == 'article') {
|
if (!showFullPost && data.type == 'article') {
|
||||||
return Container(
|
return Container(
|
||||||
@ -65,6 +126,9 @@ class PostItem extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: data,
|
data: data,
|
||||||
|
isAuthor: isAuthor,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
if (onDeleted != null) {}
|
if (onDeleted != null) {}
|
||||||
},
|
},
|
||||||
@ -116,6 +180,8 @@ class PostItem extends StatelessWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
showComments: showComments,
|
showComments: showComments,
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onChanged: _onChanged,
|
onChanged: _onChanged,
|
||||||
).padding(left: 8, right: 14),
|
).padding(left: 8, right: 14),
|
||||||
],
|
],
|
||||||
@ -134,6 +200,8 @@ class PostItem extends StatelessWidget {
|
|||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: data,
|
data: data,
|
||||||
showMenu: showMenu,
|
showMenu: showMenu,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
if (onDeleted != null) onDeleted!();
|
if (onDeleted != null) onDeleted!();
|
||||||
},
|
},
|
||||||
@ -181,6 +249,8 @@ class PostItem extends StatelessWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
showComments: showComments,
|
showComments: showComments,
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onChanged: _onChanged,
|
onChanged: _onChanged,
|
||||||
).padding(left: 8, right: 14),
|
).padding(left: 8, right: 14),
|
||||||
],
|
],
|
||||||
@ -191,28 +261,145 @@ class PostItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PostShareImage extends StatelessWidget {
|
||||||
|
const PostShareImage({
|
||||||
|
super.key,
|
||||||
|
required this.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
final SnPost data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: 480,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_PostContentHeader(
|
||||||
|
data: data,
|
||||||
|
onDeleted: () {},
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
|
showMenu: false,
|
||||||
|
isRelativeDate: false,
|
||||||
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
_PostHeadline(
|
||||||
|
data: data,
|
||||||
|
isEnlarge: data.type == 'article',
|
||||||
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
_PostContentBody(
|
||||||
|
data: data,
|
||||||
|
isEnlarge: data.type == 'article',
|
||||||
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
if (data.repostTo != null)
|
||||||
|
_PostQuoteContent(
|
||||||
|
child: data.repostTo!,
|
||||||
|
isRelativeDate: false,
|
||||||
|
isFlatted: true,
|
||||||
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
if (data.type != 'article' && (data.preload?.attachments?.isNotEmpty ?? false))
|
||||||
|
AttachmentList(
|
||||||
|
data: data.preload!.attachments!,
|
||||||
|
isFlatted: true,
|
||||||
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (data.visibility > 0) _PostVisibilityHint(data: data),
|
||||||
|
if (data.body['content_truncated'] == true) _PostTruncatedHint(data: data),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 16),
|
||||||
|
_PostBottomAction(
|
||||||
|
data: data,
|
||||||
|
showComments: true,
|
||||||
|
showReactions: true,
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
|
onChanged: (SnPost data) {},
|
||||||
|
).padding(left: 8, right: 14),
|
||||||
|
const Divider(height: 1),
|
||||||
|
const Gap(12),
|
||||||
|
SizedBox(
|
||||||
|
height: 100,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${data.aliasPrefix} / ${data.alias ?? '#${data.id}'}',
|
||||||
|
style: GoogleFonts.robotoMono(fontSize: 17),
|
||||||
|
),
|
||||||
|
const Gap(2),
|
||||||
|
Text(
|
||||||
|
switch (data.type) {
|
||||||
|
'article' => 'postArticle'.tr(),
|
||||||
|
_ => 'postStory'.tr(),
|
||||||
|
},
|
||||||
|
style: GoogleFonts.robotoMono(fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'postImageShareAds',
|
||||||
|
style: GoogleFonts.robotoMono(fontSize: 13),
|
||||||
|
).tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
QrImageView(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
data: 'https://solsynth.dev/posts/${data.id}',
|
||||||
|
version: QrVersions.auto,
|
||||||
|
size: 100,
|
||||||
|
gapless: true,
|
||||||
|
embeddedImage: AssetImage('assets/icon/icon-light-radius.png'),
|
||||||
|
embeddedImageStyle: QrEmbeddedImageStyle(
|
||||||
|
size: Size(32, 32),
|
||||||
|
),
|
||||||
|
eyeStyle: QrEyeStyle(
|
||||||
|
eyeShape: QrEyeShape.circle,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
dataModuleStyle: QrDataModuleStyle(
|
||||||
|
dataModuleShape: QrDataModuleShape.square,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).padding(left: 16, right: 32, vertical: 8),
|
||||||
|
],
|
||||||
|
).padding(vertical: 16),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _PostBottomAction extends StatelessWidget {
|
class _PostBottomAction extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
final bool showComments;
|
final bool showComments;
|
||||||
final bool showReactions;
|
final bool showReactions;
|
||||||
final Function(SnPost data) onChanged;
|
final Function(SnPost data) onChanged;
|
||||||
|
final Function() onShare, onShareImage;
|
||||||
|
|
||||||
const _PostBottomAction({
|
const _PostBottomAction({
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.showComments,
|
required this.showComments,
|
||||||
required this.showReactions,
|
required this.showReactions,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
required this.onShare,
|
||||||
|
required this.onShareImage,
|
||||||
});
|
});
|
||||||
|
|
||||||
void _doShare() {
|
|
||||||
final url = 'https://solsynth.dev/posts/${data.id}';
|
|
||||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
|
||||||
Share.shareUri(Uri.parse(url));
|
|
||||||
} else {
|
|
||||||
Share.share(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final iconColor = Theme.of(context).colorScheme.onSurface.withAlpha(
|
final iconColor = Theme.of(context).colorScheme.onSurface.withAlpha(
|
||||||
@ -297,7 +484,8 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
..removeLast(),
|
..removeLast(),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: _doShare,
|
onTap: onShare,
|
||||||
|
onLongPress: onShareImage,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Symbols.share,
|
Symbols.share,
|
||||||
size: 20,
|
size: 20,
|
||||||
@ -369,10 +557,10 @@ class _PostHeadline extends StatelessWidget {
|
|||||||
style: TextStyle(fontSize: 13),
|
style: TextStyle(fontSize: 13),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
if (data.updatedAt != data.createdAt)
|
if (data.editedAt != null)
|
||||||
Text(
|
Text(
|
||||||
'articleEditedAt'.tr(
|
'articleEditedAt'.tr(
|
||||||
args: [DateFormat('y/M/d HH:mm').format(data.updatedAt)],
|
args: [DateFormat('y/M/d HH:mm').format(data.editedAt!)],
|
||||||
),
|
),
|
||||||
style: TextStyle(fontSize: 13),
|
style: TextStyle(fontSize: 13),
|
||||||
),
|
),
|
||||||
@ -405,15 +593,22 @@ class _PostHeadline extends StatelessWidget {
|
|||||||
|
|
||||||
class _PostContentHeader extends StatelessWidget {
|
class _PostContentHeader extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
final bool isAuthor;
|
||||||
final bool isCompact;
|
final bool isCompact;
|
||||||
|
final bool isRelativeDate;
|
||||||
final bool showMenu;
|
final bool showMenu;
|
||||||
final Function onDeleted;
|
final Function onDeleted;
|
||||||
|
final Function() onShare, onShareImage;
|
||||||
|
|
||||||
const _PostContentHeader({
|
const _PostContentHeader({
|
||||||
required this.data,
|
required this.data,
|
||||||
|
this.isAuthor = false,
|
||||||
this.isCompact = false,
|
this.isCompact = false,
|
||||||
|
this.isRelativeDate = true,
|
||||||
this.showMenu = true,
|
this.showMenu = true,
|
||||||
required this.onDeleted,
|
required this.onDeleted,
|
||||||
|
required this.onShare,
|
||||||
|
required this.onShareImage,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> _deletePost(BuildContext context) async {
|
Future<void> _deletePost(BuildContext context) async {
|
||||||
@ -441,9 +636,6 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ua = context.read<UserProvider>();
|
|
||||||
final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user!.id;
|
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
@ -479,9 +671,11 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text('@${data.publisher.name}').fontSize(13),
|
Text('@${data.publisher.name}').fontSize(13),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(RelativeTime(context).format(
|
Text(
|
||||||
data.publishedAt ?? data.createdAt,
|
isRelativeDate
|
||||||
)).fontSize(13),
|
? RelativeTime(context).format(data.publishedAt ?? data.createdAt)
|
||||||
|
: DateFormat('y/M/d HH:mm').format(data.publishedAt ?? data.createdAt),
|
||||||
|
).fontSize(13),
|
||||||
],
|
],
|
||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
],
|
],
|
||||||
@ -496,9 +690,11 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text('@${data.publisher.name}').fontSize(13),
|
Text('@${data.publisher.name}').fontSize(13),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(RelativeTime(context).format(
|
Text(
|
||||||
data.publishedAt ?? data.createdAt,
|
isRelativeDate
|
||||||
)).fontSize(13),
|
? RelativeTime(context).format(data.publishedAt ?? data.createdAt)
|
||||||
|
: DateFormat('y/M/d HH:mm').format(data.publishedAt ?? data.createdAt),
|
||||||
|
).fontSize(13),
|
||||||
],
|
],
|
||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
],
|
],
|
||||||
@ -573,6 +769,27 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const PopupMenuDivider(),
|
const PopupMenuDivider(),
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: onShare,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.share),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postShare').tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: onShareImage,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.share_reviews),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postShareImage').tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const PopupMenuDivider(),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -623,8 +840,15 @@ class _PostContentBody extends StatelessWidget {
|
|||||||
|
|
||||||
class _PostQuoteContent extends StatelessWidget {
|
class _PostQuoteContent extends StatelessWidget {
|
||||||
final SnPost child;
|
final SnPost child;
|
||||||
|
final bool isRelativeDate;
|
||||||
|
final bool isFlatted;
|
||||||
|
|
||||||
const _PostQuoteContent({super.key, required this.child});
|
const _PostQuoteContent({
|
||||||
|
super.key,
|
||||||
|
this.isRelativeDate = true,
|
||||||
|
this.isFlatted = false,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -645,14 +869,17 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: child,
|
data: child,
|
||||||
isCompact: true,
|
isCompact: true,
|
||||||
|
isRelativeDate: isRelativeDate,
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
onDeleted: () {},
|
onDeleted: () {},
|
||||||
).padding(bottom: 4),
|
).padding(bottom: 4),
|
||||||
_PostContentBody(data: child),
|
_PostContentBody(data: child),
|
||||||
if (child.visibility > 0) _PostVisibilityHint(data: child).padding(top: 4),
|
if (child.visibility > 0) _PostVisibilityHint(data: child).padding(top: 4),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16),
|
).padding(horizontal: 16),
|
||||||
if (child.preload?.attachments?.isNotEmpty ?? false)
|
if (child.type != 'article' && (child.preload?.attachments?.isNotEmpty ?? false))
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(8),
|
bottomLeft: Radius.circular(8),
|
||||||
@ -660,12 +887,15 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: AttachmentList(
|
child: AttachmentList(
|
||||||
data: child.preload!.attachments!,
|
data: child.preload!.attachments!,
|
||||||
|
isFlatted: isFlatted,
|
||||||
listPadding: const EdgeInsets.symmetric(horizontal: 12),
|
listPadding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
),
|
),
|
||||||
).padding(
|
).padding(
|
||||||
top: 8,
|
top: 8,
|
||||||
bottom: (child.preload?.attachments?.length ?? 0) > 1 ? 12 : 0,
|
bottom: (child.preload?.attachments?.length ?? 0) > 1 ? 12 : 0,
|
||||||
),
|
)
|
||||||
|
else
|
||||||
|
const Gap(8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
44
pubspec.lock
44
pubspec.lock
@ -266,10 +266,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: connectivity_plus
|
name: connectivity_plus
|
||||||
sha256: "876849631b0c7dc20f8b471a2a03142841b482438e3b707955464f5ffca3e4c3"
|
sha256: e0817759ec6d2d8e57eb234e6e57d2173931367a865850c7acea40d4b4f9c27d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.1"
|
||||||
connectivity_plus_platform_interface:
|
connectivity_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -362,18 +362,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95
|
sha256: "4fa68e53e26ab17b70ca39f072c285562cfc1589df5bb1e9295db90f6645f431"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.1.1"
|
version: "11.2.0"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: device_info_plus_platform_interface
|
name: device_info_plus_platform_interface
|
||||||
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
|
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.2"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1190,18 +1190,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce
|
sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.1"
|
version: "8.1.2"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_platform_interface
|
name: package_info_plus_platform_interface
|
||||||
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
|
sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.2"
|
||||||
pasteboard:
|
pasteboard:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1402,6 +1402,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
qr:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: qr
|
||||||
|
sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
qr_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: qr_flutter
|
||||||
|
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
relative_time:
|
relative_time:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1502,18 +1518,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: share_plus
|
name: share_plus
|
||||||
sha256: "9c9bafd4060728d7cdb2464c341743adbd79d327cb067ec7afb64583540b47c8"
|
sha256: "6327c3f233729374d0abaafd61f6846115b2a481b4feddd8534211dc10659400"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.1.2"
|
version: "10.1.3"
|
||||||
share_plus_platform_interface:
|
share_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: share_plus_platform_interface
|
name: share_plus_platform_interface
|
||||||
sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48
|
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.2"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -99,6 +99,7 @@ dependencies:
|
|||||||
package_info_plus: ^8.1.1
|
package_info_plus: ^8.1.1
|
||||||
intl: ^0.19.0
|
intl: ^0.19.0
|
||||||
screenshot: ^3.0.0
|
screenshot: ^3.0.0
|
||||||
|
qr_flutter: ^4.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user