mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-05-01 09:40:30 -05:00
[client] Show file type
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
String mimeTypeName(String mimeType) {
|
||||
final index = mimeType.indexOf(';');
|
||||
if (index > 0) {
|
||||
mimeType = mimeType.substring(0, index);
|
||||
}
|
||||
final name = _fullTypeNames[mimeType];
|
||||
if (name != null) return name;
|
||||
|
||||
final parts = mimeType.split('/');
|
||||
return _categoryNames[parts[0]] ?? 'Unknown';
|
||||
}
|
||||
|
||||
const _categoryNames = <String, String>{
|
||||
'application': 'Other',
|
||||
'text': 'Text',
|
||||
'audio': 'Audio',
|
||||
'video': 'Video',
|
||||
'image': 'Image',
|
||||
};
|
||||
|
||||
const _fullTypeNames = <String, String>{
|
||||
// Application
|
||||
'application/epub+zip': 'EPUB E-Book',
|
||||
'application/json': 'JSON',
|
||||
'application/manifest+json': 'Web Manifest',
|
||||
'application/msword': 'Word Document (Legacy)',
|
||||
'application/octet-stream': 'Binary Data',
|
||||
'application/pdf': 'PDF Document',
|
||||
'application/postscript': 'PostScript Document',
|
||||
'application/vnd.android.package-archive': 'Android Application Package',
|
||||
'application/vnd.ms-excel': 'Excel Spreadsheet (Legacy)',
|
||||
'application/vnd.ms-powerpoint': 'PowerPoint Presentation (Legacy)',
|
||||
'application/vnd.oasis.opendocument.presentation': 'OpenOffice Presentation',
|
||||
'application/vnd.oasis.opendocument.spreadsheet': 'OpenOffice Spreadsheet',
|
||||
'application/vnd.oasis.opendocument.text': 'OpenOffice Text Document',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint Presentation',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel Spreadsheet',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word Document',
|
||||
'application/x-bzip': 'BZip Archive',
|
||||
'application/x-bzip2': 'BZip Archive',
|
||||
'application/x-latex': 'LaTeX Document',
|
||||
'application/x-msdownload': 'Windows Application',
|
||||
'application/x-rar-compressed': 'RAR Archive',
|
||||
'application/x-tex': 'TeX Document',
|
||||
'application/x-sh': 'Shell Script',
|
||||
'application/x-sql': 'SQL Script',
|
||||
'application/xml': 'XML',
|
||||
'application/zip': 'Zip Archive',
|
||||
|
||||
// Audio
|
||||
'audio/aac': 'AAC Audio',
|
||||
'audio/mpeg': 'MPEG Audio',
|
||||
'audio/mp4': 'MP4 Audio',
|
||||
'audio/ogg': 'OGG Audio',
|
||||
'audio/webm': 'WEBM Audio',
|
||||
'audio/x-flac': 'FLAC Audio',
|
||||
'audio/x-wav': 'WAV Audio',
|
||||
|
||||
// Image
|
||||
'image/bmp': 'Bitmap Image',
|
||||
'image/gif': 'GIF Image',
|
||||
'image/heic': 'HEIC Image',
|
||||
'image/heif': 'HEIF Image',
|
||||
'image/jpeg': 'JPEG Image',
|
||||
'image/png': 'PNG Image',
|
||||
'image/svg+xml': 'SVG Image',
|
||||
'image/vnd.adobe.photoshop': 'Photoshop Image',
|
||||
'image/webp': 'WebP Image',
|
||||
'image/x-icon': 'Favicon Image',
|
||||
|
||||
// Text
|
||||
'text/css': 'CSS Source Code',
|
||||
'text/csv': 'Comma-Separated Values',
|
||||
'text/html': 'HTML Source Code',
|
||||
'text/ics': 'Calendar Invite',
|
||||
'text/javascript': 'JS Source Code',
|
||||
'text/markdown': 'Markdown',
|
||||
'text/plain': 'Plain Text',
|
||||
'text/vnd.dvb.subtitle': 'Subtitles',
|
||||
'text/x-c': 'C/C++ Source Code',
|
||||
'text/x-dart': 'Dart Source Code',
|
||||
'text/x-vcard': 'vCard',
|
||||
|
||||
// Video
|
||||
'video/mp4': 'MP4 Video',
|
||||
'video/mpeg': 'MPEG Video',
|
||||
'video/quicktime': 'MOV Video',
|
||||
'video/webm': 'WEBM Video',
|
||||
'video/x-matroska': 'MKV Video',
|
||||
'video/x-msvideo': 'AVI Video',
|
||||
'video/x-ms-wmv': 'WMV Video',
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import 'package:phylum/libphylum/db/db.dart';
|
||||
import 'package:phylum/libphylum/phylum_account.dart';
|
||||
|
||||
const IconData folderIcon = Icons.folder;
|
||||
const IconData fileIcon = Icons.insert_drive_file;
|
||||
const IconData defaultFileIcon = Icons.insert_drive_file;
|
||||
|
||||
extension ResourceIconExtension on Resource {
|
||||
Widget getIcon(PhylumAccount account) {
|
||||
@@ -28,6 +28,6 @@ extension ResourceVersionIconExtension on ResourceVersion {
|
||||
} else if (mimeType.startsWith("text")) {
|
||||
return const Icon(Icons.article);
|
||||
}
|
||||
return const Icon(fileIcon);
|
||||
return const Icon(defaultFileIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:offtheline/offtheline.dart';
|
||||
import 'package:phylum/libphylum/actions/action_resource.dart';
|
||||
import 'package:phylum/libphylum/db/db.dart';
|
||||
@@ -9,6 +8,7 @@ import 'package:phylum/libphylum/phylum_account.dart';
|
||||
import 'package:phylum/ui/common/responsive_dialog.dart';
|
||||
import 'package:phylum/ui/explorer/explorer_controller.dart';
|
||||
import 'package:phylum/libphylum/phylum_api_types.dart';
|
||||
import 'package:phylum/ui/explorer/mime_type_names.dart';
|
||||
import 'package:phylum/ui/explorer/resource_permissions_view.dart';
|
||||
import 'package:phylum/ui/explorer/resource_publinks_view.dart';
|
||||
import 'package:phylum/ui/explorer/resource_sync_state.dart';
|
||||
@@ -80,15 +80,7 @@ class ResourceInfoView extends StatelessWidget {
|
||||
title: Text('Type'),
|
||||
subtitle: Text('Folder'),
|
||||
)
|
||||
: StreamBuilder(
|
||||
stream: account.db.latestVersion(resource.id).watchSingleOrNull(),
|
||||
builder: (context, snapshot) {
|
||||
return ListTile(
|
||||
leading: snapshot.data?.getIcon() ?? Icon(Icons.insert_drive_file),
|
||||
title: const Text('Type'),
|
||||
subtitle: Text(snapshot.data?.mimeType ?? '<unknown>'),
|
||||
);
|
||||
}),
|
||||
: LatestVersionInfoView(resourceId: resource.id),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.event),
|
||||
title: const Text('Created'),
|
||||
@@ -125,50 +117,79 @@ class ResourceInfoView extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
}),
|
||||
if (!resource.dir)
|
||||
StreamBuilder(
|
||||
stream: account.db.latestVersion(resource.id).watchSingleOrNull(),
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.data;
|
||||
// if (!resource.dir)
|
||||
// StreamBuilder(
|
||||
// stream: account.db.latestVersion(resource.id).watchSingleOrNull(),
|
||||
// builder: (context, snapshot) {
|
||||
// final data = snapshot.data;
|
||||
|
||||
if (data == null) {
|
||||
return SizedBox();
|
||||
}
|
||||
// if (data == null) {
|
||||
// return SizedBox();
|
||||
// }
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.storage),
|
||||
title: const Text('Size'),
|
||||
subtitle: Text('${data.size.formatForDisplay()} (${data.size} B)'),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.shield),
|
||||
title: const Text('SHA-256'),
|
||||
onLongPress: () {
|
||||
Clipboard.setData(ClipboardData(text: data.sha256));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text('SHA-256 checksum copied to clipboard'),
|
||||
duration: const Duration(seconds: 2),
|
||||
));
|
||||
},
|
||||
subtitle: Text(
|
||||
data.sha256,
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
// return Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// ListTile(
|
||||
// leading: const Icon(Icons.storage),
|
||||
// title: const Text('Size'),
|
||||
// subtitle: Text('${data.size.formatForDisplay()} (${data.size} B)'),
|
||||
// ),
|
||||
// ListTile(
|
||||
// leading: const Icon(Icons.shield),
|
||||
// title: const Text('SHA-256'),
|
||||
// onLongPress: () {
|
||||
// Clipboard.setData(ClipboardData(text: data.sha256));
|
||||
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// content: Text('SHA-256 checksum copied to clipboard'),
|
||||
// duration: const Duration(seconds: 2),
|
||||
// ));
|
||||
// },
|
||||
// subtitle: Text(
|
||||
// data.sha256,
|
||||
// maxLines: 1,
|
||||
// softWrap: false,
|
||||
// overflow: TextOverflow.fade,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LatestVersionInfoView extends StatelessWidget {
|
||||
final String resourceId;
|
||||
|
||||
const LatestVersionInfoView({super.key, required this.resourceId});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder(
|
||||
stream: context.read<PhylumAccount>().db.latestVersion(resourceId).watchSingleOrNull(),
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.data;
|
||||
|
||||
if (data == null) {
|
||||
return const ListTile(
|
||||
leading: Icon(defaultFileIcon),
|
||||
title: Text('Type'),
|
||||
subtitle: Text(''),
|
||||
);
|
||||
}
|
||||
|
||||
return ListTile(
|
||||
leading: data.getIcon(),
|
||||
title: Text('Type'),
|
||||
subtitle: Text('${mimeTypeName(data.mimeType)} \u2022 ${data.size.formatForDisplay()}'),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class PendingActionsTile extends StatefulWidget {
|
||||
final String resourceId;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user