ui: Add a basic implementation of the video inline widget
This commit is contained in:
parent
b4411ab4fb
commit
69f8f1b365
@ -31,6 +31,7 @@ import "package:moxxyv2/ui/bloc/profile_bloc.dart";
|
||||
import "package:moxxyv2/ui/bloc/preferences_bloc.dart";
|
||||
import "package:moxxyv2/ui/bloc/addcontact_bloc.dart";
|
||||
import "package:moxxyv2/ui/service/download.dart";
|
||||
import "package:moxxyv2/ui/service/data.dart";
|
||||
import "package:moxxyv2/service/service.dart";
|
||||
import "package:moxxyv2/shared/commands.dart";
|
||||
import "package:moxxyv2/shared/events.dart";
|
||||
@ -51,8 +52,10 @@ void setupLogging() {
|
||||
GetIt.I.registerSingleton<Logger>(Logger("MoxxyMain"));
|
||||
}
|
||||
|
||||
void setupUIServices() {
|
||||
Future<void> setupUIServices() async {
|
||||
GetIt.I.registerSingleton<UIDownloadService>(UIDownloadService());
|
||||
GetIt.I.registerSingleton<UIDataService>(UIDataService());
|
||||
await GetIt.I.get<UIDataService>().init();
|
||||
}
|
||||
|
||||
void setupBlocs(GlobalKey<NavigatorState> navKey) {
|
||||
@ -71,7 +74,7 @@ void setupBlocs(GlobalKey<NavigatorState> navKey) {
|
||||
// TODO: Theme the switches
|
||||
void main() async {
|
||||
setupLogging();
|
||||
setupUIServices();
|
||||
await setupUIServices();
|
||||
|
||||
await initializeServiceIfNeeded();
|
||||
setupEventHandler();
|
||||
|
@ -144,6 +144,7 @@ String? guessMimeTypeFromExtension(String ext) {
|
||||
case "jpg":
|
||||
case "jpeg": return "image/jpeg";
|
||||
case "webp": return "image/webp";
|
||||
case "mp4": return "video/mp4";
|
||||
}
|
||||
|
||||
return null;
|
||||
|
19
lib/ui/service/data.dart
Normal file
19
lib/ui/service/data.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:external_path/external_path.dart";
|
||||
import "package:path/path.dart" as pathlib;
|
||||
|
||||
class UIDataService {
|
||||
late String _thumbnailBase;
|
||||
|
||||
UIDataService();
|
||||
|
||||
Future<void> init() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final base = await ExternalPath.getExternalStoragePublicDirectory(ExternalPath.DIRECTORY_PICTURES);
|
||||
_thumbnailBase = pathlib.join(base, "Moxxy", ".thumbnail");
|
||||
}
|
||||
|
||||
// The base path for thumbnails
|
||||
String get thumbnailBase => _thumbnailBase;
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
import "dart:io";
|
||||
|
||||
import "package:moxxyv2/shared/models/message.dart";
|
||||
import "package:moxxyv2/ui/service/data.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/bottom.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/blurhash.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/playbutton.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/helpers.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/media/image.dart";
|
||||
import "package:moxxyv2/ui/widgets/chat/media/file.dart";
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:path/path.dart" as pathlib;
|
||||
import "package:external_path/external_path.dart";
|
||||
import "package:get_it/get_it.dart";
|
||||
import "package:video_compress/video_compress.dart";
|
||||
import "package:open_file/open_file.dart";
|
||||
|
||||
@ -45,42 +47,93 @@ class _VideoChatWidgetState extends State<VideoChatWidget> {
|
||||
final double maxWidth;
|
||||
final Message message;
|
||||
|
||||
String _thumbnailPath;
|
||||
bool _hasThumbnail;
|
||||
|
||||
_VideoChatWidgetState(
|
||||
this.message,
|
||||
this.maxWidth,
|
||||
this.timestamp,
|
||||
this.radius,
|
||||
) : _thumbnailPath = "", _hasThumbnail = true;
|
||||
);
|
||||
|
||||
Future<String> _getThumbnailPath() async {
|
||||
final base = await ExternalPath.getExternalStoragePublicDirectory(ExternalPath.DIRECTORY_PICTURES);
|
||||
return pathlib.join(base, "Moxxy", ".thumbnail", message.conversationJid, pathlib.basename(message.mediaUrl!));
|
||||
/// Returns the path of a possible thumbnail for the video. Does not imply that the file
|
||||
/// exists.
|
||||
String _getThumbnailPath() {
|
||||
final base = GetIt.I.get<UIDataService>().thumbnailBase;
|
||||
return pathlib.join(base, message.conversationJid, pathlib.basename(message.mediaUrl!));
|
||||
}
|
||||
|
||||
/// Generate the thumbnail if needed.
|
||||
Future<bool> _thumbnailFuture() async {
|
||||
final thumbnailFile = File(_getThumbnailPath());
|
||||
if (await thumbnailFile.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Thumbnail does not exist
|
||||
final sourceFile = File(message.mediaUrl!);
|
||||
if (await sourceFile.exists()) {
|
||||
final bytes = await VideoCompress.getByteThumbnail(
|
||||
sourceFile.path,
|
||||
quality: 75
|
||||
);
|
||||
await thumbnailFile.writeAsBytes(bytes!);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Source file also does not exist. Return "error".
|
||||
return false;
|
||||
}
|
||||
|
||||
Widget _buildNonDownloaded() {
|
||||
// TODO
|
||||
return const SizedBox();
|
||||
if (message.thumbnailData != null) {}
|
||||
|
||||
return FileChatWidget(
|
||||
message,
|
||||
timestamp,
|
||||
extra: ElevatedButton(
|
||||
// TODO
|
||||
onPressed: () {},
|
||||
child: const Text("Download")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDownloading() {
|
||||
// TODO
|
||||
return const SizedBox();
|
||||
if (message.thumbnailData != null) {}
|
||||
|
||||
return FileChatWidget(
|
||||
message,
|
||||
timestamp,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildVideo() {
|
||||
return FutureBuilder<bool>(
|
||||
future: _thumbnailFuture(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.data!) {
|
||||
return ImageBaseChatWidget(
|
||||
message.mediaUrl!,
|
||||
radius,
|
||||
Image.file(File(message.mediaUrl!)),
|
||||
Image.file(File(_getThumbnailPath())),
|
||||
MessageBubbleBottom(
|
||||
message,
|
||||
timestamp: timestamp,
|
||||
),
|
||||
extra: const PlayButton()
|
||||
);
|
||||
} else {
|
||||
// TODO: Error
|
||||
return const Text("Error");
|
||||
}
|
||||
} else {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Widget _innerBuild() {
|
||||
|
Loading…
Reference in New Issue
Block a user