together_mobile/lib/screens/message/components/attachment_container.dart

121 lines
3.6 KiB
Dart
Raw Permalink Normal View History

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
2024-04-09 17:23:28 +08:00
import '/common/constants.dart';
import '/database/box_type.dart';
import '/models/init_get_it.dart';
import '/models/user_model.dart';
class AttachmentContainer extends StatefulWidget {
const AttachmentContainer({
super.key,
required this.isMyself,
required this.filename,
required this.onTapImage,
});
final bool isMyself;
final String filename;
final Function(String) onTapImage;
@override
State<AttachmentContainer> createState() => _AttachmentContainerState();
}
class _AttachmentContainerState extends State<AttachmentContainer>
with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
return Container(
margin: const EdgeInsets.only(
bottom: 15,
),
constraints: const BoxConstraints(
maxHeight: 150,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
),
child: ValueListenableBuilder(
valueListenable: widget.isMyself
? Hive.box<AttachmentProgress>('attachment_send')
.listenable(keys: [widget.filename])
: Hive.box<AttachmentProgress>('attachment_receive')
.listenable(keys: [widget.filename]),
builder: (context, apBox, _) {
double progress = apBox.get(widget.filename)!.progress;
String filePath =
'${getIt.get<UserProfile>().baseImageDir}/${widget.filename}';
bool isFileExists = File(filePath).existsSync();
_controller.animateTo(
progress,
duration: const Duration(milliseconds: 500),
);
return Stack(
children: [
GestureDetector(
onTap: () {
widget.onTapImage(widget.filename);
},
child: progress == 1.0 || isFileExists
? Image.file(File(filePath))
: Image.asset('assets/images/loading.gif'),
),
if (progress < 1.0)
Positioned.fill(
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.center,
constraints: const BoxConstraints.expand(),
color: const Color.fromARGB(255, 32, 32, 32)
.withOpacity(0.3),
child: Text(
'${(_animation.value * 100).toStringAsFixed(0)}%',
style: const TextStyle(
fontSize: 20,
color: kUnAvailableColor,
),
),
),
CircularProgressIndicator(
value: _animation.value,
color: kSecondaryColor,
strokeWidth: 4,
),
],
),
),
],
);
},
),
);
}
}