2023-10-01 18:40:14 +08:00
|
|
|
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';
|
2023-10-01 18:40:14 +08:00
|
|
|
|
|
|
|
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'),
|
|
|
|
),
|
2023-10-05 12:12:56 +08:00
|
|
|
if (progress < 1.0)
|
2023-10-01 18:40:14 +08:00
|
|
|
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,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|