Preview for SND files

This commit is contained in:
2025-09-01 00:34:55 +08:00
parent f98e603e82
commit 3417c51a3b
3 changed files with 56 additions and 4 deletions

View File

@@ -951,7 +951,6 @@
"chatBreak15m": "15m", "chatBreak15m": "15m",
"chatBreak30m": "30m", "chatBreak30m": "30m",
"chatBreakCustomMinutes": "Custom (minutes)", "chatBreakCustomMinutes": "Custom (minutes)",
"chatBreakEnterMinutes": "Enter minutes",
"errorGeneric": "Error: {}", "errorGeneric": "Error: {}",
"searchMessages": "Search Messages", "searchMessages": "Search Messages",
"messagesCount": "{} messages", "messagesCount": "{} messages",
@@ -960,5 +959,6 @@
"searchMessagesHint": "Search messages...", "searchMessagesHint": "Search messages...",
"searchLinks": "Links", "searchLinks": "Links",
"searchAttachments": "Attachments", "searchAttachments": "Attachments",
"noMessagesFound": "No messages found" "noMessagesFound": "No messages found",
"openInBrowser": "Open in Browser"
} }

View File

@@ -857,5 +857,6 @@
"expiresIn": "过期时间(秒)", "expiresIn": "过期时间(秒)",
"isOidc": "OIDC 兼容", "isOidc": "OIDC 兼容",
"statusPresent": "至今", "statusPresent": "至今",
"accountAutomated": "机器人" "accountAutomated": "机器人",
"openInBrowser": "在浏览器中打开"
} }

View File

@@ -1,8 +1,10 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/file.dart'; import 'package:island/models/file.dart';
import 'package:island/pods/config.dart'; import 'package:island/pods/config.dart';
@@ -10,6 +12,7 @@ import 'package:island/services/time.dart';
import 'package:island/widgets/content/audio.dart'; import 'package:island/widgets/content/audio.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'image.dart'; import 'image.dart';
import 'video.dart'; import 'video.dart';
@@ -32,6 +35,16 @@ class CloudFileWidget extends HookConsumerWidget {
final serverUrl = ref.watch(serverUrlProvider); final serverUrl = ref.watch(serverUrlProvider);
final uri = '$serverUrl/drive/files/${item.id}'; final uri = '$serverUrl/drive/files/${item.id}';
String formatFileSize(int bytes) {
if (bytes <= 0) return '0 B';
if (bytes < 1024) return '$bytes B';
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(2)} KB';
if (bytes < 1024 * 1024 * 1024) {
return '${(bytes / (1024 * 1024)).toStringAsFixed(2)} MB';
}
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB';
}
var ratio = var ratio =
item.fileMeta?['ratio'] is num item.fileMeta?['ratio'] is num
? item.fileMeta!['ratio'].toDouble() ? item.fileMeta!['ratio'].toDouble()
@@ -60,7 +73,45 @@ class CloudFileWidget extends HookConsumerWidget {
child: UniversalAudio(uri: uri, filename: item.name), child: UniversalAudio(uri: uri, filename: item.name),
), ),
), ),
_ => Text('Unable render for ${item.mimeType}'), _ => Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Symbols.insert_drive_file,
size: 48,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const Gap(8),
Text(
item.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
Text(
formatFileSize(item.size),
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
const Gap(8),
TextButton.icon(
onPressed: () {
launchUrlString(
'https://fs.solian.app/files/${item.id}',
mode: LaunchMode.externalApplication,
);
},
icon: const Icon(Symbols.launch),
label: Text('openInBrowser').tr(),
),
],
).padding(all: 8),
}; };
if (heroTag != null) { if (heroTag != null) {