🐛 Fix share via image errored
This commit is contained in:
		@@ -22,12 +22,14 @@ class AttachmentItem extends StatelessWidget {
 | 
			
		||||
  final SnAttachment? data;
 | 
			
		||||
  final String? heroTag;
 | 
			
		||||
  final BoxFit fit;
 | 
			
		||||
  final FilterQuality? filterQuality;
 | 
			
		||||
 | 
			
		||||
  const AttachmentItem({
 | 
			
		||||
    super.key,
 | 
			
		||||
    this.fit = BoxFit.cover,
 | 
			
		||||
    required this.data,
 | 
			
		||||
    required this.heroTag,
 | 
			
		||||
    this.filterQuality,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Widget _buildContent(BuildContext context) {
 | 
			
		||||
@@ -47,6 +49,7 @@ class AttachmentItem extends StatelessWidget {
 | 
			
		||||
            sn.getAttachmentUrl(data!.rid),
 | 
			
		||||
            key: Key('attachment-${data!.rid}-$tag'),
 | 
			
		||||
            fit: fit,
 | 
			
		||||
            filterQuality: filterQuality,
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
      case 'video':
 | 
			
		||||
@@ -83,13 +86,16 @@ class _AttachmentItemSensitiveBlur extends StatefulWidget {
 | 
			
		||||
  final Widget child;
 | 
			
		||||
  final bool isCompact;
 | 
			
		||||
 | 
			
		||||
  const _AttachmentItemSensitiveBlur({required this.child, this.isCompact = false});
 | 
			
		||||
  const _AttachmentItemSensitiveBlur(
 | 
			
		||||
      {required this.child, this.isCompact = false});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<_AttachmentItemSensitiveBlur> createState() => _AttachmentItemSensitiveBlurState();
 | 
			
		||||
  State<_AttachmentItemSensitiveBlur> createState() =>
 | 
			
		||||
      _AttachmentItemSensitiveBlurState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AttachmentItemSensitiveBlurState extends State<_AttachmentItemSensitiveBlur> {
 | 
			
		||||
class _AttachmentItemSensitiveBlurState
 | 
			
		||||
    extends State<_AttachmentItemSensitiveBlur> {
 | 
			
		||||
  bool _doesShow = false;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@@ -124,10 +130,15 @@ class _AttachmentItemSensitiveBlurState extends State<_AttachmentItemSensitiveBl
 | 
			
		||||
                      Text(
 | 
			
		||||
                        'sensitiveContentDescription',
 | 
			
		||||
                        textAlign: TextAlign.center,
 | 
			
		||||
                      ).tr().fontSize(14).textColor(Colors.white.withOpacity(0.8)),
 | 
			
		||||
                      )
 | 
			
		||||
                          .tr()
 | 
			
		||||
                          .fontSize(14)
 | 
			
		||||
                          .textColor(Colors.white.withOpacity(0.8)),
 | 
			
		||||
                    if (!widget.isCompact) const Gap(16),
 | 
			
		||||
                    InkWell(
 | 
			
		||||
                      child: Text('sensitiveContentReveal').tr().textColor(Colors.white),
 | 
			
		||||
                      child: Text('sensitiveContentReveal')
 | 
			
		||||
                          .tr()
 | 
			
		||||
                          .textColor(Colors.white),
 | 
			
		||||
                      onTap: () {
 | 
			
		||||
                        setState(() => _doesShow = !_doesShow);
 | 
			
		||||
                      },
 | 
			
		||||
@@ -137,7 +148,9 @@ class _AttachmentItemSensitiveBlurState extends State<_AttachmentItemSensitiveBl
 | 
			
		||||
              ).center(),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ).opacity(_doesShow ? 0 : 1, animate: true).animate(const Duration(milliseconds: 300), Curves.easeInOut),
 | 
			
		||||
        )
 | 
			
		||||
            .opacity(_doesShow ? 0 : 1, animate: true)
 | 
			
		||||
            .animate(const Duration(milliseconds: 300), Curves.easeInOut),
 | 
			
		||||
        if (_doesShow)
 | 
			
		||||
          Positioned(
 | 
			
		||||
            top: 0,
 | 
			
		||||
@@ -174,10 +187,12 @@ class _AttachmentItemContentVideo extends StatefulWidget {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<_AttachmentItemContentVideo> createState() => _AttachmentItemContentVideoState();
 | 
			
		||||
  State<_AttachmentItemContentVideo> createState() =>
 | 
			
		||||
      _AttachmentItemContentVideoState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo> {
 | 
			
		||||
class _AttachmentItemContentVideoState
 | 
			
		||||
    extends State<_AttachmentItemContentVideo> {
 | 
			
		||||
  bool _showContent = false;
 | 
			
		||||
  bool _showOriginal = false;
 | 
			
		||||
 | 
			
		||||
@@ -188,7 +203,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo
 | 
			
		||||
    setState(() => _showContent = true);
 | 
			
		||||
    MediaKit.ensureInitialized();
 | 
			
		||||
    final sn = context.read<SnNetworkProvider>();
 | 
			
		||||
    final url = _showOriginal ? sn.getAttachmentUrl(widget.data.rid) : sn.getAttachmentUrl(widget.data.compressed!.rid);
 | 
			
		||||
    final url = _showOriginal
 | 
			
		||||
        ? sn.getAttachmentUrl(widget.data.rid)
 | 
			
		||||
        : sn.getAttachmentUrl(widget.data.compressed!.rid);
 | 
			
		||||
    _videoPlayer = Player();
 | 
			
		||||
    _videoController = VideoController(_videoPlayer!);
 | 
			
		||||
    _videoPlayer!.open(Media(url), play: !widget.isAutoload);
 | 
			
		||||
@@ -201,7 +218,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo
 | 
			
		||||
    final sn = context.read<SnNetworkProvider>();
 | 
			
		||||
    _videoPlayer?.open(
 | 
			
		||||
      Media(
 | 
			
		||||
        _showOriginal ? sn.getAttachmentUrl(widget.data.rid) : sn.getAttachmentUrl(widget.data.compressed!.rid),
 | 
			
		||||
        _showOriginal
 | 
			
		||||
            ? sn.getAttachmentUrl(widget.data.rid)
 | 
			
		||||
            : sn.getAttachmentUrl(widget.data.compressed!.rid),
 | 
			
		||||
      ),
 | 
			
		||||
      play: true,
 | 
			
		||||
    );
 | 
			
		||||
@@ -283,7 +302,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo
 | 
			
		||||
                          ),
 | 
			
		||||
                          Text(
 | 
			
		||||
                            Duration(
 | 
			
		||||
                              milliseconds: (widget.data.data['duration'] ?? 0).toInt() * 1000,
 | 
			
		||||
                              milliseconds:
 | 
			
		||||
                                  (widget.data.data['duration'] ?? 0).toInt() *
 | 
			
		||||
                                      1000,
 | 
			
		||||
                            ).toString(),
 | 
			
		||||
                            style: GoogleFonts.robotoMono(
 | 
			
		||||
                              fontSize: 12,
 | 
			
		||||
@@ -346,7 +367,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo
 | 
			
		||||
            MaterialDesktopCustomButton(
 | 
			
		||||
              iconSize: 24,
 | 
			
		||||
              onPressed: _toggleOriginal,
 | 
			
		||||
              icon: _showOriginal ? const Icon(Symbols.high_quality, size: 24) : const Icon(Symbols.sd, size: 24),
 | 
			
		||||
              icon: _showOriginal
 | 
			
		||||
                  ? const Icon(Symbols.high_quality, size: 24)
 | 
			
		||||
                  : const Icon(Symbols.sd, size: 24),
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
@@ -354,8 +377,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo
 | 
			
		||||
        child: Video(
 | 
			
		||||
          controller: _videoController!,
 | 
			
		||||
          aspectRatio: ratio,
 | 
			
		||||
          controls:
 | 
			
		||||
              !kIsWeb && (Platform.isAndroid || Platform.isIOS) ? MaterialVideoControls : MaterialDesktopVideoControls,
 | 
			
		||||
          controls: !kIsWeb && (Platform.isAndroid || Platform.isIOS)
 | 
			
		||||
              ? MaterialVideoControls
 | 
			
		||||
              : MaterialDesktopVideoControls,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
@@ -378,10 +402,12 @@ class _AttachmentItemContentAudio extends StatefulWidget {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<_AttachmentItemContentAudio> createState() => _AttachmentItemContentAudioState();
 | 
			
		||||
  State<_AttachmentItemContentAudio> createState() =>
 | 
			
		||||
      _AttachmentItemContentAudioState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AttachmentItemContentAudioState extends State<_AttachmentItemContentAudio> {
 | 
			
		||||
class _AttachmentItemContentAudioState
 | 
			
		||||
    extends State<_AttachmentItemContentAudio> {
 | 
			
		||||
  bool _showContent = false;
 | 
			
		||||
 | 
			
		||||
  double? _draggingValue;
 | 
			
		||||
@@ -552,8 +578,12 @@ class _AttachmentItemContentAudioState extends State<_AttachmentItemContentAudio
 | 
			
		||||
                            overlayShape: SliderComponentShape.noOverlay,
 | 
			
		||||
                          ),
 | 
			
		||||
                          child: Slider(
 | 
			
		||||
                            secondaryTrackValue: _bufferedPosition.inMilliseconds.abs().toDouble(),
 | 
			
		||||
                            value: _draggingValue?.abs() ?? _position.inMilliseconds.toDouble().abs(),
 | 
			
		||||
                            secondaryTrackValue: _bufferedPosition
 | 
			
		||||
                                .inMilliseconds
 | 
			
		||||
                                .abs()
 | 
			
		||||
                                .toDouble(),
 | 
			
		||||
                            value: _draggingValue?.abs() ??
 | 
			
		||||
                                _position.inMilliseconds.toDouble().abs(),
 | 
			
		||||
                            min: 0,
 | 
			
		||||
                            max: math
 | 
			
		||||
                                .max(
 | 
			
		||||
@@ -593,7 +623,9 @@ class _AttachmentItemContentAudioState extends State<_AttachmentItemContentAudio
 | 
			
		||||
                  ),
 | 
			
		||||
                  const Gap(16),
 | 
			
		||||
                  IconButton.filled(
 | 
			
		||||
                    icon: _isPlaying ? const Icon(Symbols.pause) : const Icon(Symbols.play_arrow),
 | 
			
		||||
                    icon: _isPlaying
 | 
			
		||||
                        ? const Icon(Symbols.pause)
 | 
			
		||||
                        : const Icon(Symbols.play_arrow),
 | 
			
		||||
                    onPressed: () {
 | 
			
		||||
                      _audioPlayer!.playOrPause();
 | 
			
		||||
                    },
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ class AttachmentList extends StatefulWidget {
 | 
			
		||||
  final double? minWidth;
 | 
			
		||||
  final double? maxWidth;
 | 
			
		||||
  final EdgeInsets? padding;
 | 
			
		||||
  final FilterQuality? filterQuality;
 | 
			
		||||
 | 
			
		||||
  const AttachmentList({
 | 
			
		||||
    super.key,
 | 
			
		||||
@@ -33,23 +34,27 @@ class AttachmentList extends StatefulWidget {
 | 
			
		||||
    this.minWidth,
 | 
			
		||||
    this.maxWidth,
 | 
			
		||||
    this.padding,
 | 
			
		||||
    this.filterQuality,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  static const BorderRadius kDefaultRadius = BorderRadius.all(Radius.circular(8));
 | 
			
		||||
  static const BorderRadius kDefaultRadius =
 | 
			
		||||
      BorderRadius.all(Radius.circular(8));
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<AttachmentList> createState() => _AttachmentListState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
  late final List<String> heroTags = List.generate(widget.data.length, (_) => const Uuid().v4());
 | 
			
		||||
  late final List<String> heroTags =
 | 
			
		||||
      List.generate(widget.data.length, (_) => const Uuid().v4());
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return LayoutBuilder(
 | 
			
		||||
      builder: (context, layoutConstraints) {
 | 
			
		||||
        final borderSide =
 | 
			
		||||
            widget.bordered ? BorderSide(width: 1, color: Theme.of(context).dividerColor) : BorderSide.none;
 | 
			
		||||
        final borderSide = widget.bordered
 | 
			
		||||
            ? BorderSide(width: 1, color: Theme.of(context).dividerColor)
 | 
			
		||||
            : BorderSide.none;
 | 
			
		||||
        final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
 | 
			
		||||
        final constraints = BoxConstraints(
 | 
			
		||||
          minWidth: widget.minWidth ?? 80,
 | 
			
		||||
@@ -58,13 +63,13 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
 | 
			
		||||
        if (widget.data.isEmpty) return const SizedBox.shrink();
 | 
			
		||||
        if (widget.data.length == 1) {
 | 
			
		||||
          final singleAspectRatio =
 | 
			
		||||
              widget.data[0]?.data['ratio']?.toDouble() ??
 | 
			
		||||
          final singleAspectRatio = widget.data[0]?.data['ratio']?.toDouble() ??
 | 
			
		||||
              switch (widget.data[0]?.mimetype.split('/').firstOrNull) {
 | 
			
		||||
                'audio' => 16 / 9,
 | 
			
		||||
                'video' => 16 / 9,
 | 
			
		||||
                _ => 1,
 | 
			
		||||
              }.toDouble();
 | 
			
		||||
              }
 | 
			
		||||
                  .toDouble();
 | 
			
		||||
 | 
			
		||||
          return Container(
 | 
			
		||||
            padding: widget.padding ?? EdgeInsets.zero,
 | 
			
		||||
@@ -80,12 +85,18 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
                  ),
 | 
			
		||||
                  child: ClipRRect(
 | 
			
		||||
                    borderRadius: AttachmentList.kDefaultRadius,
 | 
			
		||||
                    child: AttachmentItem(data: widget.data[0], heroTag: heroTags[0], fit: widget.fit),
 | 
			
		||||
                    child: AttachmentItem(
 | 
			
		||||
                      data: widget.data[0],
 | 
			
		||||
                      heroTag: heroTags[0],
 | 
			
		||||
                      fit: widget.fit,
 | 
			
		||||
                      filterQuality: widget.filterQuality,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              onTap: () {
 | 
			
		||||
                if (widget.data.firstOrNull?.mediaType != SnMediaType.image) return;
 | 
			
		||||
                if (widget.data.firstOrNull?.mediaType != SnMediaType.image)
 | 
			
		||||
                  return;
 | 
			
		||||
                context.pushTransparentRoute(
 | 
			
		||||
                  AttachmentZoomView(
 | 
			
		||||
                    data: widget.data.where((ele) => ele != null).cast(),
 | 
			
		||||
@@ -100,8 +111,10 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final fullOfImage =
 | 
			
		||||
            widget.data.where((ele) => ele?.mediaType == SnMediaType.image).length == widget.data.length;
 | 
			
		||||
        final fullOfImage = widget.data
 | 
			
		||||
                .where((ele) => ele?.mediaType == SnMediaType.image)
 | 
			
		||||
                .length ==
 | 
			
		||||
            widget.data.length;
 | 
			
		||||
 | 
			
		||||
        if (widget.gridded && fullOfImage) {
 | 
			
		||||
          return Container(
 | 
			
		||||
@@ -117,29 +130,36 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
                crossAxisCount: math.min(widget.data.length, 2),
 | 
			
		||||
                crossAxisSpacing: 4,
 | 
			
		||||
                mainAxisSpacing: 4,
 | 
			
		||||
                children:
 | 
			
		||||
                    widget.data
 | 
			
		||||
                        .mapIndexed(
 | 
			
		||||
                          (idx, ele) => GestureDetector(
 | 
			
		||||
                            child: Container(
 | 
			
		||||
                              constraints: constraints,
 | 
			
		||||
                              child: AttachmentItem(data: ele, heroTag: heroTags[idx], fit: BoxFit.cover),
 | 
			
		||||
                            ),
 | 
			
		||||
                            onTap: () {
 | 
			
		||||
                              if (widget.data[idx]!.mediaType != SnMediaType.image) return;
 | 
			
		||||
                              context.pushTransparentRoute(
 | 
			
		||||
                                AttachmentZoomView(
 | 
			
		||||
                                  data: widget.data.where((ele) => ele != null).cast(),
 | 
			
		||||
                                  initialIndex: idx,
 | 
			
		||||
                                  heroTags: heroTags,
 | 
			
		||||
                                ),
 | 
			
		||||
                                backgroundColor: Colors.black.withOpacity(0.7),
 | 
			
		||||
                                rootNavigator: true,
 | 
			
		||||
                              );
 | 
			
		||||
                            },
 | 
			
		||||
                children: widget.data
 | 
			
		||||
                    .mapIndexed(
 | 
			
		||||
                      (idx, ele) => GestureDetector(
 | 
			
		||||
                        child: Container(
 | 
			
		||||
                          constraints: constraints,
 | 
			
		||||
                          child: AttachmentItem(
 | 
			
		||||
                            data: ele,
 | 
			
		||||
                            heroTag: heroTags[idx],
 | 
			
		||||
                            fit: BoxFit.cover,
 | 
			
		||||
                            filterQuality: widget.filterQuality,
 | 
			
		||||
                          ),
 | 
			
		||||
                        )
 | 
			
		||||
                        .toList(),
 | 
			
		||||
                        ),
 | 
			
		||||
                        onTap: () {
 | 
			
		||||
                          if (widget.data[idx]!.mediaType != SnMediaType.image)
 | 
			
		||||
                            return;
 | 
			
		||||
                          context.pushTransparentRoute(
 | 
			
		||||
                            AttachmentZoomView(
 | 
			
		||||
                              data: widget.data
 | 
			
		||||
                                  .where((ele) => ele != null)
 | 
			
		||||
                                  .cast(),
 | 
			
		||||
                              initialIndex: idx,
 | 
			
		||||
                              heroTags: heroTags,
 | 
			
		||||
                            ),
 | 
			
		||||
                            backgroundColor: Colors.black.withOpacity(0.7),
 | 
			
		||||
                            rootNavigator: true,
 | 
			
		||||
                          );
 | 
			
		||||
                        },
 | 
			
		||||
                      ),
 | 
			
		||||
                    )
 | 
			
		||||
                    .toList(),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
@@ -156,22 +176,26 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
            child: ClipRRect(
 | 
			
		||||
              borderRadius: AttachmentList.kDefaultRadius,
 | 
			
		||||
              child: Column(
 | 
			
		||||
                children:
 | 
			
		||||
                    widget.data
 | 
			
		||||
                        .mapIndexed(
 | 
			
		||||
                          (idx, ele) => GestureDetector(
 | 
			
		||||
                            child: AspectRatio(
 | 
			
		||||
                              aspectRatio: ele?.data['ratio']?.toDouble() ?? 1,
 | 
			
		||||
                              child: Container(
 | 
			
		||||
                                constraints: constraints,
 | 
			
		||||
                                child: AttachmentItem(data: ele, heroTag: heroTags[idx], fit: BoxFit.cover),
 | 
			
		||||
                              ),
 | 
			
		||||
                children: widget.data
 | 
			
		||||
                    .mapIndexed(
 | 
			
		||||
                      (idx, ele) => GestureDetector(
 | 
			
		||||
                        child: AspectRatio(
 | 
			
		||||
                          aspectRatio: ele?.data['ratio']?.toDouble() ?? 1,
 | 
			
		||||
                          child: Container(
 | 
			
		||||
                            constraints: constraints,
 | 
			
		||||
                            child: AttachmentItem(
 | 
			
		||||
                              data: ele,
 | 
			
		||||
                              heroTag: heroTags[idx],
 | 
			
		||||
                              fit: BoxFit.cover,
 | 
			
		||||
                              filterQuality: widget.filterQuality,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        )
 | 
			
		||||
                        .expand((ele) => [ele, const Divider(height: 1)])
 | 
			
		||||
                        .toList()
 | 
			
		||||
                      ..removeLast(),
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    )
 | 
			
		||||
                    .expand((ele) => [ele, const Divider(height: 1)])
 | 
			
		||||
                    .toList()
 | 
			
		||||
                  ..removeLast(),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
@@ -189,16 +213,22 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
                itemCount: widget.data.length,
 | 
			
		||||
                itemBuilder: (context, idx) {
 | 
			
		||||
                  return Container(
 | 
			
		||||
                    constraints: constraints.copyWith(maxWidth: widget.maxWidth),
 | 
			
		||||
                    constraints:
 | 
			
		||||
                        constraints.copyWith(maxWidth: widget.maxWidth),
 | 
			
		||||
                    child: AspectRatio(
 | 
			
		||||
                      aspectRatio: (widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
 | 
			
		||||
                      aspectRatio:
 | 
			
		||||
                          (widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
 | 
			
		||||
                      child: GestureDetector(
 | 
			
		||||
                        onTap: () {
 | 
			
		||||
                          if (widget.data[idx]?.mediaType != SnMediaType.image) return;
 | 
			
		||||
                          if (widget.data[idx]?.mediaType != SnMediaType.image)
 | 
			
		||||
                            return;
 | 
			
		||||
                          context.pushTransparentRoute(
 | 
			
		||||
                            AttachmentZoomView(
 | 
			
		||||
                              data:
 | 
			
		||||
                                  widget.data.where((ele) => ele != null && ele.mediaType == SnMediaType.image).cast(),
 | 
			
		||||
                              data: widget.data
 | 
			
		||||
                                  .where((ele) =>
 | 
			
		||||
                                      ele != null &&
 | 
			
		||||
                                      ele.mediaType == SnMediaType.image)
 | 
			
		||||
                                  .cast(),
 | 
			
		||||
                              initialIndex: idx,
 | 
			
		||||
                              heroTags: heroTags,
 | 
			
		||||
                            ),
 | 
			
		||||
@@ -212,18 +242,25 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
                            Container(
 | 
			
		||||
                              decoration: BoxDecoration(
 | 
			
		||||
                                color: backgroundColor,
 | 
			
		||||
                                border: Border(top: borderSide, bottom: borderSide),
 | 
			
		||||
                                border:
 | 
			
		||||
                                    Border(top: borderSide, bottom: borderSide),
 | 
			
		||||
                                borderRadius: AttachmentList.kDefaultRadius,
 | 
			
		||||
                              ),
 | 
			
		||||
                              child: ClipRRect(
 | 
			
		||||
                                borderRadius: AttachmentList.kDefaultRadius,
 | 
			
		||||
                                child: AttachmentItem(data: widget.data[idx], heroTag: heroTags[idx]),
 | 
			
		||||
                                child: AttachmentItem(
 | 
			
		||||
                                  data: widget.data[idx],
 | 
			
		||||
                                  heroTag: heroTags[idx],
 | 
			
		||||
                                  filterQuality: widget.filterQuality,
 | 
			
		||||
                                ),
 | 
			
		||||
                              ),
 | 
			
		||||
                            ),
 | 
			
		||||
                            Positioned(
 | 
			
		||||
                              right: 8,
 | 
			
		||||
                              bottom: 8,
 | 
			
		||||
                              child: Chip(label: Text('${idx + 1}/${widget.data.length}')),
 | 
			
		||||
                              child: Chip(
 | 
			
		||||
                                  label:
 | 
			
		||||
                                      Text('${idx + 1}/${widget.data.length}')),
 | 
			
		||||
                            ),
 | 
			
		||||
                          ],
 | 
			
		||||
                        ),
 | 
			
		||||
@@ -245,5 +282,6 @@ class _AttachmentListState extends State<AttachmentList> {
 | 
			
		||||
 | 
			
		||||
class _AttachmentListScrollBehavior extends MaterialScrollBehavior {
 | 
			
		||||
  @override
 | 
			
		||||
  Set<PointerDeviceKind> get dragDevices => {PointerDeviceKind.touch, PointerDeviceKind.mouse};
 | 
			
		||||
  Set<PointerDeviceKind> get dragDevices =>
 | 
			
		||||
      {PointerDeviceKind.touch, PointerDeviceKind.mouse};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,6 @@ class PostItem extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  void _doShareViaPicture(BuildContext context) async {
 | 
			
		||||
    final box = context.findRenderObject() as RenderBox?;
 | 
			
		||||
    context.showSnackbar('postSharingViaPicture'.tr());
 | 
			
		||||
 | 
			
		||||
    final controller = ScreenshotController();
 | 
			
		||||
    final capturedImage = await controller.captureFromLongWidget(
 | 
			
		||||
@@ -160,9 +159,9 @@ class PostItem extends StatelessWidget {
 | 
			
		||||
          child: Material(
 | 
			
		||||
            child: MultiProvider(
 | 
			
		||||
              providers: [
 | 
			
		||||
                // Create a copy of environments
 | 
			
		||||
                Provider<SnNetworkProvider>(create: (_) => context.read()),
 | 
			
		||||
                ChangeNotifierProvider<ConfigProvider>(
 | 
			
		||||
                    create: (_) => context.read()),
 | 
			
		||||
                Provider<UserDirectoryProvider>(create: (_) => context.read()),
 | 
			
		||||
              ],
 | 
			
		||||
              child: ResponsiveBreakpoints.builder(
 | 
			
		||||
                breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
 | 
			
		||||
@@ -507,6 +506,8 @@ class PostShareImageWidget extends StatelessWidget {
 | 
			
		||||
            StyledWidget(AttachmentList(
 | 
			
		||||
              data: data.preload!.attachments!,
 | 
			
		||||
              columned: true,
 | 
			
		||||
              fit: BoxFit.contain,
 | 
			
		||||
              filterQuality: FilterQuality.high,
 | 
			
		||||
            )).padding(horizontal: 16, bottom: 8),
 | 
			
		||||
          Column(
 | 
			
		||||
            crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
 
 | 
			
		||||
@@ -34,11 +34,14 @@ class UniversalImage extends StatelessWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
 | 
			
		||||
    final double? resizeHeight = cacheHeight != null ? (cacheHeight! * devicePixelRatio) : null;
 | 
			
		||||
    final double? resizeWidth = cacheWidth != null ? (cacheWidth! * devicePixelRatio) : null;
 | 
			
		||||
    final double? resizeHeight =
 | 
			
		||||
        cacheHeight != null ? (cacheHeight! * devicePixelRatio) : null;
 | 
			
		||||
    final double? resizeWidth =
 | 
			
		||||
        cacheWidth != null ? (cacheWidth! * devicePixelRatio) : null;
 | 
			
		||||
 | 
			
		||||
    return Image(
 | 
			
		||||
      filterQuality: filterQuality ?? context.read<ConfigProvider>().imageQuality,
 | 
			
		||||
      filterQuality:
 | 
			
		||||
          filterQuality ?? context.read<ConfigProvider>().imageQuality,
 | 
			
		||||
      image: kIsWeb
 | 
			
		||||
          ? UniversalImage.provider(url)
 | 
			
		||||
          : ResizeImage(
 | 
			
		||||
@@ -52,7 +55,8 @@ class UniversalImage extends StatelessWidget {
 | 
			
		||||
      fit: fit,
 | 
			
		||||
      loadingBuilder: noProgressIndicator
 | 
			
		||||
          ? null
 | 
			
		||||
          : (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
 | 
			
		||||
          : (BuildContext context, Widget child,
 | 
			
		||||
              ImageChunkEvent? loadingProgress) {
 | 
			
		||||
              if (loadingProgress == null) return child;
 | 
			
		||||
              return Container(
 | 
			
		||||
                constraints: BoxConstraints(maxHeight: 80),
 | 
			
		||||
@@ -61,12 +65,15 @@ class UniversalImage extends StatelessWidget {
 | 
			
		||||
                    tween: Tween(
 | 
			
		||||
                      begin: 0,
 | 
			
		||||
                      end: loadingProgress.expectedTotalBytes != null
 | 
			
		||||
                          ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
 | 
			
		||||
                          ? loadingProgress.cumulativeBytesLoaded /
 | 
			
		||||
                              loadingProgress.expectedTotalBytes!
 | 
			
		||||
                          : 0,
 | 
			
		||||
                    ),
 | 
			
		||||
                    duration: const Duration(milliseconds: 300),
 | 
			
		||||
                    builder: (context, value, _) => CircularProgressIndicator(
 | 
			
		||||
                      value: loadingProgress.expectedTotalBytes != null ? value.toDouble() : null,
 | 
			
		||||
                      value: loadingProgress.expectedTotalBytes != null
 | 
			
		||||
                          ? value.toDouble()
 | 
			
		||||
                          : null,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
@@ -114,6 +121,7 @@ class AutoResizeUniversalImage extends StatelessWidget {
 | 
			
		||||
  final BoxFit? fit;
 | 
			
		||||
  final bool noProgressIndicator;
 | 
			
		||||
  final bool noErrorWidget;
 | 
			
		||||
  final FilterQuality? filterQuality;
 | 
			
		||||
 | 
			
		||||
  const AutoResizeUniversalImage(
 | 
			
		||||
    this.url, {
 | 
			
		||||
@@ -123,6 +131,7 @@ class AutoResizeUniversalImage extends StatelessWidget {
 | 
			
		||||
    this.fit,
 | 
			
		||||
    this.noProgressIndicator = false,
 | 
			
		||||
    this.noErrorWidget = false,
 | 
			
		||||
    this.filterQuality,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@@ -137,6 +146,7 @@ class AutoResizeUniversalImage extends StatelessWidget {
 | 
			
		||||
        noErrorWidget: noErrorWidget,
 | 
			
		||||
        cacheHeight: constraints.maxHeight,
 | 
			
		||||
        cacheWidth: constraints.maxWidth,
 | 
			
		||||
        filterQuality: filterQuality,
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user