chat support update
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -4,11 +4,13 @@
|
|||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="kent_logistics_app"
|
android:label="kent_logistics_app"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
|||||||
145
lib/screens/chat_file_viewer.dart
Normal file
145
lib/screens/chat_file_viewer.dart
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
import 'package:chewie/chewie.dart';
|
||||||
|
import 'package:flutter_pdfview/flutter_pdfview.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
class ChatFileViewer {
|
||||||
|
/// Entry point used by chat screen
|
||||||
|
static void open(
|
||||||
|
BuildContext context, {
|
||||||
|
required String url,
|
||||||
|
required String fileType,
|
||||||
|
}) {
|
||||||
|
if (fileType.startsWith('image/')) {
|
||||||
|
_openImage(context, url);
|
||||||
|
} else if (fileType.startsWith('video/')) {
|
||||||
|
_openVideo(context, url);
|
||||||
|
} else if (fileType == 'application/pdf') {
|
||||||
|
_openPdf(context, url);
|
||||||
|
} else {
|
||||||
|
_downloadFile(context, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// IMAGE VIEWER
|
||||||
|
// ===========================
|
||||||
|
static void _openImage(BuildContext context, String url) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => Scaffold(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
appBar: AppBar(backgroundColor: Colors.black),
|
||||||
|
body: PhotoView(
|
||||||
|
imageProvider: NetworkImage(url),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// VIDEO VIEWER
|
||||||
|
// ===========================
|
||||||
|
static void _openVideo(BuildContext context, String url) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => _VideoPlayerPage(url: url),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// PDF VIEWER
|
||||||
|
// ===========================
|
||||||
|
static Future<void> _openPdf(
|
||||||
|
BuildContext context, String url) async {
|
||||||
|
final dir = await getTemporaryDirectory();
|
||||||
|
final path = "${dir.path}/chat.pdf";
|
||||||
|
|
||||||
|
await Dio().download(url, path);
|
||||||
|
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => Scaffold(
|
||||||
|
appBar: AppBar(title: const Text("PDF")),
|
||||||
|
body: PDFView(filePath: path),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// FILE DOWNLOAD
|
||||||
|
// ===========================
|
||||||
|
static Future<void> _downloadFile(
|
||||||
|
BuildContext context, String url) async {
|
||||||
|
final dir = await getExternalStorageDirectory();
|
||||||
|
final fileName = url.split('/').last;
|
||||||
|
final path = "${dir!.path}/$fileName";
|
||||||
|
|
||||||
|
await Dio().download(url, path);
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text("File downloaded: $fileName")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// VIDEO PLAYER WIDGET
|
||||||
|
// ===========================
|
||||||
|
class _VideoPlayerPage extends StatefulWidget {
|
||||||
|
final String url;
|
||||||
|
const _VideoPlayerPage({required this.url});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_VideoPlayerPage> createState() => _VideoPlayerPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VideoPlayerPageState extends State<_VideoPlayerPage> {
|
||||||
|
late VideoPlayerController _videoController;
|
||||||
|
ChewieController? _chewieController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_videoController = VideoPlayerController.network(widget.url)
|
||||||
|
..initialize().then((_) {
|
||||||
|
setState(() {
|
||||||
|
_chewieController = ChewieController(
|
||||||
|
videoPlayerController: _videoController,
|
||||||
|
autoPlay: true,
|
||||||
|
looping: false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_videoController.dispose();
|
||||||
|
_chewieController?.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text("Video")),
|
||||||
|
body: Center(
|
||||||
|
child: _chewieController == null
|
||||||
|
? const CircularProgressIndicator()
|
||||||
|
: Chewie(controller: _chewieController!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,14 @@ import '../services/chat_service.dart';
|
|||||||
import '../services/reverb_socket_service.dart';
|
import '../services/reverb_socket_service.dart';
|
||||||
import '../services/dio_client.dart';
|
import '../services/dio_client.dart';
|
||||||
import '../providers/chat_unread_provider.dart';
|
import '../providers/chat_unread_provider.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:file_selector/file_selector.dart';
|
||||||
|
import 'chat_file_viewer.dart';
|
||||||
|
import '../widgets/chat_file_preview.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ChatScreen extends StatefulWidget {
|
class ChatScreen extends StatefulWidget {
|
||||||
const ChatScreen({super.key});
|
const ChatScreen({super.key});
|
||||||
@@ -41,6 +49,17 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
_initChat();
|
_initChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _pickAndSendFile() async {
|
||||||
|
final XFile? file = await openFile();
|
||||||
|
|
||||||
|
if (file == null || ticketId == null) return;
|
||||||
|
|
||||||
|
final dartFile = File(file.path);
|
||||||
|
|
||||||
|
await _chatService.sendFile(ticketId!, dartFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// INIT CHAT
|
// INIT CHAT
|
||||||
// ============================
|
// ============================
|
||||||
@@ -135,6 +154,77 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Future<void> _openUrl(String url) async {
|
||||||
|
// final uri = Uri.parse(url);
|
||||||
|
//
|
||||||
|
// if (await canLaunchUrl(uri)) {
|
||||||
|
// await launchUrl(
|
||||||
|
// uri,
|
||||||
|
// mode: LaunchMode.externalApplication,
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// debugPrint("❌ Cannot launch URL: $url");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Widget _buildMessageContent({
|
||||||
|
String? message,
|
||||||
|
String? filePath,
|
||||||
|
String? fileType,
|
||||||
|
required bool isUser,
|
||||||
|
}) {
|
||||||
|
final textColor = isUser ? Colors.white : Colors.black;
|
||||||
|
|
||||||
|
if (filePath == null) {
|
||||||
|
return Text(message ?? '', style: TextStyle(color: textColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
final url = "${DioClient.baseUrl}/storage/$filePath";
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
ChatFileViewer.open(
|
||||||
|
context,
|
||||||
|
url: url,
|
||||||
|
fileType: fileType ?? '',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(_iconForFile(fileType), color: textColor),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
_labelForFile(fileType),
|
||||||
|
style: TextStyle(color: textColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IconData _iconForFile(String? type) {
|
||||||
|
if (type == null) return Icons.insert_drive_file;
|
||||||
|
if (type.startsWith('image/')) return Icons.image;
|
||||||
|
if (type.startsWith('video/')) return Icons.play_circle_fill;
|
||||||
|
if (type == 'application/pdf') return Icons.picture_as_pdf;
|
||||||
|
return Icons.insert_drive_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _labelForFile(String? type) {
|
||||||
|
if (type == null) return "File";
|
||||||
|
if (type.startsWith('image/')) return "Image";
|
||||||
|
if (type.startsWith('video/')) return "Video";
|
||||||
|
if (type == 'application/pdf') return "PDF";
|
||||||
|
return "Download file";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Widget _buildMessages() {
|
Widget _buildMessages() {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
controller: _scrollCtrl,
|
controller: _scrollCtrl,
|
||||||
@@ -144,21 +234,32 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
final msg = messages[index];
|
final msg = messages[index];
|
||||||
final isUser = msg['sender_type'] == 'App\\Models\\User';
|
final isUser = msg['sender_type'] == 'App\\Models\\User';
|
||||||
|
|
||||||
|
final String? filePath = msg['file_path'];
|
||||||
|
final String? fileType = msg['file_type'];
|
||||||
|
final String? message = msg['message'];
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment:
|
alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
|
||||||
isUser ? Alignment.centerRight : Alignment.centerLeft,
|
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isUser ? Colors.blue : Colors.grey.shade300,
|
color: isUser ? Colors.blue : Colors.grey.shade300,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Text(
|
|
||||||
msg['message'] ?? '',
|
// 🔽 ONLY THIS PART CHANGED
|
||||||
|
child: filePath == null
|
||||||
|
? Text(
|
||||||
|
message ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: isUser ? Colors.white : Colors.black,
|
color: isUser ? Colors.white : Colors.black,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
: ChatFilePreview(
|
||||||
|
filePath: filePath,
|
||||||
|
fileType: fileType ?? '',
|
||||||
|
isUser: isUser,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -170,11 +271,17 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.attach_file),
|
||||||
|
onPressed: _pickAndSendFile,
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: _messageCtrl,
|
controller: _messageCtrl,
|
||||||
decoration:
|
decoration: const InputDecoration(
|
||||||
const InputDecoration(hintText: "Type message"),
|
hintText: "Type message",
|
||||||
|
border: InputBorder.none,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
@@ -185,4 +292,5 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../config/api_config.dart';
|
import '../config/api_config.dart';
|
||||||
|
|
||||||
@@ -38,4 +40,25 @@ class ChatService {
|
|||||||
|
|
||||||
await dio.post('/user/chat/send/$ticketId', data: form);
|
await dio.post('/user/chat/send/$ticketId', data: form);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// SEND FILE (image/video/pdf/excel)
|
||||||
|
// ---------------------------
|
||||||
|
Future<void> sendFile(int ticketId, File file) async {
|
||||||
|
final formData = FormData.fromMap({
|
||||||
|
'file': await MultipartFile.fromFile(
|
||||||
|
file.path,
|
||||||
|
filename: file.path.split('/').last,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
await dio.post(
|
||||||
|
"/user/chat/send/$ticketId",
|
||||||
|
|
||||||
|
data: formData,
|
||||||
|
options: Options(
|
||||||
|
headers: {'Content-Type': 'multipart/form-data'},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import '../providers/auth_provider.dart';
|
|||||||
import 'token_interceptor.dart';
|
import 'token_interceptor.dart';
|
||||||
|
|
||||||
class DioClient {
|
class DioClient {
|
||||||
static Dio? _dio; // Singleton instance
|
static Dio? _dio;
|
||||||
|
|
||||||
|
static const String baseUrl = "http://10.11.236.74:8000";
|
||||||
|
|
||||||
static Dio getInstance(BuildContext context) {
|
static Dio getInstance(BuildContext context) {
|
||||||
if (_dio == null) {
|
if (_dio == null) {
|
||||||
|
|||||||
108
lib/widgets/chat_file_preview.dart
Normal file
108
lib/widgets/chat_file_preview.dart
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../services/dio_client.dart';
|
||||||
|
import '../screens/chat_file_viewer.dart';
|
||||||
|
|
||||||
|
class ChatFilePreview extends StatelessWidget {
|
||||||
|
final String filePath;
|
||||||
|
final String fileType;
|
||||||
|
final bool isUser;
|
||||||
|
|
||||||
|
const ChatFilePreview({
|
||||||
|
super.key,
|
||||||
|
required this.filePath,
|
||||||
|
required this.fileType,
|
||||||
|
required this.isUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final url = "${DioClient.baseUrl}/storage/$filePath";
|
||||||
|
final textColor = isUser ? Colors.white : Colors.black;
|
||||||
|
|
||||||
|
// IMAGE PREVIEW
|
||||||
|
if (fileType.startsWith('image/')) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => ChatFileViewer.open(
|
||||||
|
context,
|
||||||
|
url: url,
|
||||||
|
fileType: fileType,
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.network(
|
||||||
|
url,
|
||||||
|
width: 180,
|
||||||
|
height: 120,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// VIDEO PREVIEW
|
||||||
|
if (fileType.startsWith('video/')) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => ChatFileViewer.open(
|
||||||
|
context,
|
||||||
|
url: url,
|
||||||
|
fileType: fileType,
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 180,
|
||||||
|
height: 120,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black26,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.videocam,
|
||||||
|
size: 50,
|
||||||
|
color: Colors.white70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Icon(
|
||||||
|
Icons.play_circle_fill,
|
||||||
|
size: 56,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDF / FILE PREVIEW
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => ChatFileViewer.open(
|
||||||
|
context,
|
||||||
|
url: url,
|
||||||
|
fileType: fileType,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(_fileIcon(fileType), color: textColor),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
_fileLabel(fileType),
|
||||||
|
style: TextStyle(color: textColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IconData _fileIcon(String type) {
|
||||||
|
if (type == 'application/pdf') return Icons.picture_as_pdf;
|
||||||
|
if (type.contains('excel')) return Icons.table_chart;
|
||||||
|
return Icons.insert_drive_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _fileLabel(String type) {
|
||||||
|
if (type == 'application/pdf') return "PDF document";
|
||||||
|
if (type.contains('excel')) return "Excel file";
|
||||||
|
return "Download file";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,13 +6,21 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
|
import package_info_plus
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import share_plus
|
import share_plus
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
import url_launcher_macos
|
||||||
|
import video_player_avfoundation
|
||||||
|
import wakelock_plus
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
|
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||||
|
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
192
pubspec.lock
192
pubspec.lock
@@ -9,6 +9,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.7"
|
version: "4.0.7"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -49,6 +57,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
|
chewie:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: chewie
|
||||||
|
sha256: "44bcfc5f0dfd1de290c87c9d86a61308b3282a70b63435d5557cfd60f54a69ca"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.13.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -81,6 +97,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.7"
|
version: "3.0.7"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -89,6 +113,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
dbus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dbus
|
||||||
|
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.11"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -129,6 +161,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
file_selector:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: file_selector
|
||||||
|
sha256: "5f1d15a7f17115038f433d1b0ea57513cc9e29a9d5338d166cb0bef3fa90a7a0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
|
file_selector_android:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: file_selector_android
|
||||||
|
sha256: "1ce58b609289551f8ec07265476720e77d19764339cc1d8e4df3c4d34dac6499"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.1+17"
|
||||||
|
file_selector_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_ios
|
||||||
|
sha256: fe9f52123af16bba4ad65bd7e03defbbb4b172a38a8e6aaa2a869a0c56a5f5fb
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.3+2"
|
||||||
file_selector_linux:
|
file_selector_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -153,6 +209,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
|
file_selector_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_web
|
||||||
|
sha256: c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.4+2"
|
||||||
file_selector_windows:
|
file_selector_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -182,6 +246,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
|
flutter_pdfview:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_pdfview
|
||||||
|
sha256: c0b2cc4ebf461a5a4bb9312a165222475a7d93845c7a0703f4abb7f442eb6d54
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.3"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -208,6 +280,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.5"
|
version: "4.0.5"
|
||||||
|
html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: html
|
||||||
|
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.6"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -376,6 +456,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
package_info_plus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus
|
||||||
|
sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.0.0"
|
||||||
|
package_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_platform_interface
|
||||||
|
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.1"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -456,6 +552,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
photo_view:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: photo_view
|
||||||
|
sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -637,6 +741,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
|
url_launcher:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: url_launcher
|
||||||
|
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.2"
|
||||||
|
url_launcher_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_android
|
||||||
|
sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.20"
|
||||||
|
url_launcher_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_ios
|
||||||
|
sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.4"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -645,6 +773,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.2"
|
version: "3.2.2"
|
||||||
|
url_launcher_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_macos
|
||||||
|
sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.3"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -685,6 +821,46 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
|
video_player:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: video_player
|
||||||
|
sha256: "096bc28ce10d131be80dfb00c223024eb0fba301315a406728ab43dd99c45bdf"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.10.1"
|
||||||
|
video_player_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: video_player_android
|
||||||
|
sha256: a8dc4324f67705de057678372bedb66cd08572fe7c495605ac68c5f503324a39
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.8.15"
|
||||||
|
video_player_avfoundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: video_player_avfoundation
|
||||||
|
sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.8.4"
|
||||||
|
video_player_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: video_player_platform_interface
|
||||||
|
sha256: "57c5d73173f76d801129d0531c2774052c5a7c11ccb962f1830630decd9f24ec"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.6.0"
|
||||||
|
video_player_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: video_player_web
|
||||||
|
sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -693,6 +869,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.0.0"
|
version: "15.0.0"
|
||||||
|
wakelock_plus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: wakelock_plus
|
||||||
|
sha256: "9296d40c9adbedaba95d1e704f4e0b434be446e2792948d0e4aa977048104228"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
wakelock_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: wakelock_plus_platform_interface
|
||||||
|
sha256: "036deb14cd62f558ca3b73006d52ce049fabcdcb2eddfe0bf0fe4e8a943b5cf2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ dependencies:
|
|||||||
pdf: ^3.11.0
|
pdf: ^3.11.0
|
||||||
pusher_channels_flutter: ^2.3.0
|
pusher_channels_flutter: ^2.3.0
|
||||||
web_socket_channel: ^2.4.0
|
web_socket_channel: ^2.4.0
|
||||||
|
url_launcher: ^6.2.6
|
||||||
|
file_selector: ^1.0.3
|
||||||
|
file_selector_android: ^0.5.0
|
||||||
|
photo_view: ^0.15.0
|
||||||
|
video_player: ^2.9.1
|
||||||
|
chewie: ^1.8.1
|
||||||
|
flutter_pdfview: ^1.3.2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
|
|||||||
Reference in New Issue
Block a user