Jelajahi Sumber

Revert "cssc"

This reverts commit abe8713359570cf690afeb76d8719e8c6454cbb4.
ub3lal 1 bulan lalu
induk
melakukan
ef7549aa53

+ 1 - 2
lib/cashed_image.dart

@@ -1,2 +1 @@
-export 'src/CashedNetworkImage.dart';
-export 'src/CachedNetworkImageWidget.dart';
+export 'src/CashedNetworkImageWidget.dart';

+ 0 - 46
lib/src/CachedNetworkImageWidget.dart

@@ -1,46 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:network_image_cached/cashed_image.dart';
-
-class CachedNetworkImageWidget extends StatelessWidget {
-  const CachedNetworkImageWidget({
-    super.key,
-    required this.imageUrl,
-    this.count = 10,
-    this.width,
-    this.height,
-    this.placeholder,
-    this.errorWidget,
-    this.cached = true,
-    this.httpHeaders,
-    this.cacheKey,
-    this.loadwidget = const CircularProgressIndicator(),
-    required this.imageBuilder,
-  });
-  final String imageUrl;
-  final int count;
-  final double? width;
-  final double? height;
-  final Widget? placeholder;
-  final Widget? errorWidget;
-  final bool cached;
-  final Map<String, String>? httpHeaders;
-  final String? cacheKey;
-  final Widget? loadwidget;
-  final ImageWidgetBuilder imageBuilder;
-  @override
-  Widget build(BuildContext context) {
-    return CachedNetworkImage(
-      cacheKey: cacheKey,
-      imageBuilder: imageBuilder,
-      imageUrl: imageUrl,
-      cached: cached,
-      count: count,
-      errorWidget: errorWidget,
-      height: height,
-      httpHeaders: httpHeaders,
-      loadwidget: loadwidget,
-      placeholder: placeholder,
-      width: width,
-    );
-  }
-}

+ 224 - 0
lib/src/CashedNetworkImageWidget.dart

@@ -0,0 +1,224 @@
+import 'dart:ui' as ui;
+import 'dart:ui';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_cache_manager/flutter_cache_manager.dart';
+import 'package:network_image_cached/src/http_request.dart';
+
+import 'bloc/cashed_image_bloc.dart'
+    show
+        CashedImageBloc,
+        CashedImageGetErrorState,
+        CashedImageGetState,
+        CashedImageState,
+        GetStartImageEvent;
+
+typedef ImageWidgetBuilder =
+    Widget Function(BuildContext context, ImageProvider imageProvider);
+
+class CachedNetworkImageWidget extends StatefulWidget {
+  final String imageUrl;
+  final int count;
+  final double? width;
+  final double? height;
+  final Widget? placeholder;
+  final Widget? errorWidget;
+  final bool cached;
+  final Map<String, String>? httpHeaders;
+  final String? cacheKey;
+  final Widget? loadwidget;
+  final ImageWidgetBuilder imageBuilder;
+
+  const CachedNetworkImageWidget({
+    super.key,
+    required this.imageUrl,
+    required this.cacheKey,
+    this.count = 10,
+    this.height,
+    this.width,
+    this.errorWidget,
+    this.placeholder,
+    this.cached = true,
+    this.loadwidget = const CircularProgressIndicator(),
+    this.httpHeaders,
+    required this.imageBuilder,
+  });
+
+  @override
+  CachedNetworkImageWidgetState createState() =>
+      CachedNetworkImageWidgetState();
+}
+
+class CachedNetworkImageWidgetState extends State<CachedNetworkImageWidget>
+    with AutomaticKeepAliveClientMixin {
+  late final CashedImageBloc bloc;
+
+  @override
+  void initState() {
+    bloc = CashedImageBloc();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    bloc.close();
+    super.dispose();
+  }
+
+  @override
+  bool get wantKeepAlive => true;
+
+  @override
+  Widget build(BuildContext context) {
+    super.build(context);
+
+    return BlocProvider(
+      create: (context) => bloc
+        ..add(
+          GetStartImageEvent(
+            httpHeaders: widget.httpHeaders,
+            url: widget.imageUrl,
+            cached: widget.cached,
+            count: widget.count,
+            cachkey: widget.cacheKey,
+          ),
+        ),
+      child: BlocBuilder<CashedImageBloc, CashedImageState>(
+        builder: (context, state) {
+          if (state is CashedImageGetErrorState) {
+            return SizedBox(
+              width: widget.width,
+              height: widget.height,
+              child: widget.errorWidget ?? Center(child: Icon(Icons.error)),
+            );
+          }
+
+          if (state is CashedImageGetState) {
+            ImageProvider imageProvider = MemoryImage(state.bytes);
+            return widget.imageBuilder(context, imageProvider!);
+          }
+          return SizedBox(
+            width: widget.width,
+            height: widget.height,
+            child:
+                widget.placeholder ??
+                Center(child: widget.loadwidget ?? CircularProgressIndicator()),
+          );
+        },
+      ),
+    );
+  }
+}
+
+class CachedNetworkImageProvider
+    extends ImageProvider<CachedNetworkImageProvider> {
+  final String imageUrl;
+  final int count;
+  final BoxFit fit;
+  final double? width;
+  final double? height;
+  final Widget? placeholder;
+  final Widget? errorWidget;
+  final bool cached;
+  final String? cacheKey;
+  final Widget? loadwidget;
+  final Map<String, String>? httpHeaders;
+  const CachedNetworkImageProvider({
+    required this.imageUrl,
+    required this.cacheKey,
+    required this.fit,
+    this.count = 10,
+    this.height,
+    this.width,
+    this.errorWidget,
+    this.placeholder,
+    this.cached = true,
+    this.loadwidget = const CircularProgressIndicator(),
+    this.httpHeaders,
+  });
+
+  @override
+  ImageStreamCompleter loadImage(
+    CachedNetworkImageProvider key,
+    ImageDecoderCallback decode,
+  ) {
+    // 1. Создаём Future, который загрузит и декодирует изображение
+
+    // 2. Возвращаем ImageStreamCompleter, который управляет потоком загрузки
+    return MultiFrameImageStreamCompleter(
+      codec: _loadAndDecodeImage(decode),
+      scale: 1.0,
+      informationCollector: () => <DiagnosticsNode>[
+        DiagnosticsProperty<CachedNetworkImageProvider>(
+          'Image provider',
+          key,
+          showName: false,
+        ),
+      ],
+    );
+  }
+
+  // Вспомогательный метод: загружает байты и декодирует в ui.Image
+  Future<ui.Codec> _loadAndDecodeImage(ImageDecoderCallback decode) async {
+    try {
+      // 1. Отправляем HTTP‑запрос
+      HttpGetImage httpGetImage = HttpGetImage(
+        url: imageUrl,
+        count: count,
+        httpHeaders: httpHeaders,
+      );
+      // 2. Декодируем байты в ui.Image
+      DefaultCacheManager defaultCacheManager = DefaultCacheManager();
+      if (cached) {
+        FileInfo? fileInfo;
+        if (cacheKey != null) {
+          fileInfo = await defaultCacheManager.getFileFromCache(cacheKey!);
+        } else {
+          fileInfo = await defaultCacheManager.getFileFromCache(imageUrl);
+        }
+
+        if (fileInfo != null) {
+          final decodedImage = await decode(
+            await ImmutableBuffer.fromUint8List(
+              await fileInfo.file.readAsBytes(),
+            ),
+          );
+
+          return decodedImage;
+        }
+      }
+      Uint8List img;
+      try {
+        img = await httpGetImage.getDataObjectIsolate();
+        if (cached) {
+          if (cacheKey != null) {
+            defaultCacheManager.putFile(cacheKey!, img);
+          } else {
+            defaultCacheManager.putFile(imageUrl, img);
+          }
+        }
+      } catch (e) {
+        throw Exception('Failed to load image: $e');
+      }
+
+      final decodedImage = await decode(
+        await ImmutableBuffer.fromUint8List(img),
+      );
+
+      return decodedImage;
+    } catch (e) {
+      // Если ошибка — бросаем исключение (будет обработано в Image widget)
+      throw Exception('Failed to load image: $e');
+    }
+  }
+
+  @override
+  Future<CachedNetworkImageProvider> obtainKey(
+    ImageConfiguration configuration,
+  ) {
+    return SynchronousFuture<CachedNetworkImageProvider>(this);
+  }
+}