A framework for building convergent cross-platform Nextcloud clients using Flutter.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.3 KiB

part of '../neon_files.dart';
3 years ago
class FilePreview extends StatelessWidget {
const FilePreview({
required this.bloc,
required this.details,
this.size = const Size.square(40),
3 years ago
this.color,
this.borderRadius,
this.withBackground = false,
3 years ago
super.key,
}) : assert(
(borderRadius != null && withBackground) || borderRadius == null,
'withBackground needs to be true when borderRadius is set',
);
3 years ago
final FilesBloc bloc;
final FileDetails details;
final Size size;
3 years ago
final Color? color;
final BorderRadius? borderRadius;
final bool withBackground;
3 years ago
@override
Widget build(final BuildContext context) {
3 years ago
final color = this.color ?? Theme.of(context).colorScheme.primary;
return SizedBox.fromSize(
size: size,
child: Builder(
builder: (final context) {
3 years ago
if (details.isDirectory) {
return Icon(
MdiIcons.folder,
color: color,
size: size.shortestSide,
3 years ago
);
}
return ValueListenableBuilder<bool>(
valueListenable: bloc.options.showPreviewsOption,
builder: (final context, final showPreviews, final child) {
if (showPreviews && (details.hasPreview ?? false)) {
final account = Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!;
final preview = FilePreviewImage(
account: account,
file: details,
size: size,
);
if (withBackground) {
return NeonImageWrapper(
borderRadius: borderRadius,
child: preview,
);
}
return preview;
}
return child!;
},
child: FileIcon(
details.name,
color: color,
size: size.shortestSide,
),
3 years ago
);
},
),
);
}
}
class FilePreviewImage extends NeonCachedImage {
factory FilePreviewImage({
required final Account account,
required final FileDetails file,
required final Size size,
}) {
final width = size.width.toInt();
final height = size.height.toInt();
final path = file.path.join('/');
final cacheKey = '${account.id}-preview-$path-$width-$height';
return FilePreviewImage._(
account: account,
file: file,
size: size,
cacheKey: cacheKey,
path: path,
width: width,
height: height,
);
}
FilePreviewImage._({
required final Account account,
required final FileDetails file,
required Size super.size,
required super.cacheKey,
required final String path,
required final int width,
required final int height,
}) : super.custom(
getImage: () async => account.client.core.preview.getPreview(
file: path,
x: width,
y: height,
),
writeCache: (final cacheManager, final data) async {
await cacheManager.putFile(
cacheKey,
data,
maxAge: const Duration(days: 7),
eTag: file.etag,
);
},
isSvgHint: file.mimeType?.contains('svg') ?? false,
);
}