PDF rendering

This commit is contained in:
2025-10-02 02:10:45 +08:00
parent 8fe3a664a6
commit 337ae39e08
10 changed files with 224 additions and 78 deletions

View File

@@ -295,6 +295,8 @@ PODS:
- super_native_extensions (0.0.1): - super_native_extensions (0.0.1):
- Flutter - Flutter
- SwiftyGif (5.4.5) - SwiftyGif (5.4.5)
- syncfusion_flutter_pdfviewer (0.0.1):
- Flutter
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- volume_controller (0.0.1): - volume_controller (0.0.1):
@@ -347,6 +349,7 @@ DEPENDENCIES:
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`) - sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`) - super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
- syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`) - volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
@@ -464,6 +467,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin" :path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
super_native_extensions: super_native_extensions:
:path: ".symlinks/plugins/super_native_extensions/ios" :path: ".symlinks/plugins/super_native_extensions/ios"
syncfusion_flutter_pdfviewer:
:path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
volume_controller: volume_controller:
@@ -539,6 +544,7 @@ SPEC CHECKSUMS:
sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1 sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4 super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12 volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556

View File

@@ -13,6 +13,7 @@ import 'package:island/utils/format.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:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
import 'package:island/widgets/data_saving_gate.dart'; import 'package:island/widgets/data_saving_gate.dart';
@@ -49,7 +50,8 @@ class CloudFileWidget extends HookConsumerWidget {
var ratio = meta['ratio'] is num ? (meta['ratio'] as num).toDouble() : 1.0; var ratio = meta['ratio'] is num ? (meta['ratio'] as num).toDouble() : 1.0;
if (ratio == 0) ratio = 1.0; if (ratio == 0) ratio = 1.0;
Widget cloudImage() => UniversalImage(uri: uri, blurHash: blurHash, fit: fit); Widget cloudImage() =>
UniversalImage(uri: uri, blurHash: blurHash, fit: fit);
Widget cloudVideo() => CloudVideoWidget(item: item); Widget cloudVideo() => CloudVideoWidget(item: item);
Widget dataPlaceHolder(IconData icon) => _DataSavingPlaceholder( Widget dataPlaceHolder(IconData icon) => _DataSavingPlaceholder(
@@ -59,14 +61,50 @@ class CloudFileWidget extends HookConsumerWidget {
}, },
); );
if (item.mimeType == 'application/pdf') {
return Stack(
children: [
SizedBox(height: 600, child: SfPdfViewer.network(uri)),
Positioned(
top: 8,
left: 8,
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Symbols.picture_as_pdf, size: 16, color: Colors.white),
const SizedBox(width: 4),
const Text(
'PDF',
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
),
),
],
);
}
var content = switch (item.mimeType?.split('/').firstOrNull) { var content = switch (item.mimeType?.split('/').firstOrNull) {
'image' => AspectRatio( 'image' => AspectRatio(
aspectRatio: ratio, aspectRatio: ratio,
child: (useInternalGate && dataSaving && !unlocked.value) ? dataPlaceHolder(Symbols.image) : cloudImage(), child:
(useInternalGate && dataSaving && !unlocked.value)
? dataPlaceHolder(Symbols.image)
: cloudImage(),
), ),
'video' => AspectRatio( 'video' => AspectRatio(
aspectRatio: ratio, aspectRatio: ratio,
child: (useInternalGate && dataSaving && !unlocked.value) ? dataPlaceHolder(Symbols.play_arrow) : cloudVideo(), child:
(useInternalGate && dataSaving && !unlocked.value)
? dataPlaceHolder(Symbols.play_arrow)
: cloudVideo(),
), ),
'audio' => Center( 'audio' => Center(
child: ConstrainedBox( child: ConstrainedBox(
@@ -140,8 +178,11 @@ class _DataSavingPlaceholder extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon(icon, size: 36, Icon(
color: Theme.of(context).colorScheme.onSurfaceVariant), icon,
size: 36,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const Gap(8), const Gap(8),
Text( Text(
'dataSavingHint'.tr(), 'dataSavingHint'.tr(),
@@ -154,6 +195,7 @@ class _DataSavingPlaceholder extends StatelessWidget {
); );
} }
} }
class CloudVideoWidget extends HookConsumerWidget { class CloudVideoWidget extends HookConsumerWidget {
final SnCloudFile item; final SnCloudFile item;
const CloudVideoWidget({super.key, required this.item}); const CloudVideoWidget({super.key, required this.item});
@@ -357,26 +399,31 @@ class ProfilePictureWidget extends ConsumerWidget {
final serverUrl = ref.watch(serverUrlProvider); final serverUrl = ref.watch(serverUrlProvider);
final String? id = file?.id ?? fileId; final String? id = file?.id ?? fileId;
final fallback = Icon( final fallback =
Icon(
fallbackIcon ?? Symbols.account_circle, fallbackIcon ?? Symbols.account_circle,
size: radius, size: radius,
color: fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer, color:
fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
).center(); ).center();
return ClipRRect( return ClipRRect(
borderRadius: borderRadius == null borderRadius:
borderRadius == null
? BorderRadius.all(Radius.circular(radius)) ? BorderRadius.all(Radius.circular(radius))
: BorderRadius.all(Radius.circular(borderRadius!)), : BorderRadius.all(Radius.circular(borderRadius!)),
child: Container( child: Container(
width: radius * 2, width: radius * 2,
height: radius * 2, height: radius * 2,
color: Theme.of(context).colorScheme.primaryContainer, color: Theme.of(context).colorScheme.primaryContainer,
child: id == null child:
id == null
? fallback ? fallback
: DataSavingGate( : DataSavingGate(
bypass: true, bypass: true,
placeholder: fallback, placeholder: fallback,
content: () => UniversalImage( content:
() => UniversalImage(
uri: '$serverUrl/drive/files/$id', uri: '$serverUrl/drive/files/$id',
fit: BoxFit.cover, fit: BoxFit.cover,
), ),

View File

@@ -13,8 +13,14 @@ import 'package:island/widgets/post/compose_card.dart';
class PostComposeDialog extends HookConsumerWidget { class PostComposeDialog extends HookConsumerWidget {
final SnPost? originalPost; final SnPost? originalPost;
final PostComposeInitialState? initialState; final PostComposeInitialState? initialState;
final bool isBottomSheet;
const PostComposeDialog({super.key, this.originalPost, this.initialState}); const PostComposeDialog({
super.key,
this.originalPost,
this.initialState,
this.isBottomSheet = false,
});
static Future<SnPost?> show( static Future<SnPost?> show(
BuildContext context, { BuildContext context, {
@@ -23,12 +29,15 @@ class PostComposeDialog extends HookConsumerWidget {
}) { }) {
return showDialog<SnPost>( return showDialog<SnPost>(
context: context, context: context,
useRootNavigator: false, useRootNavigator: true,
builder: builder:
(context) => PostComposeDialog( (context) => Padding(
padding: EdgeInsets.all(16),
child: PostComposeDialog(
originalPost: originalPost, originalPost: originalPost,
initialState: initialState, initialState: initialState,
), ),
),
); );
} }

View File

@@ -23,6 +23,7 @@
#include <screen_retriever_linux/screen_retriever_linux_plugin.h> #include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h> #include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <super_native_extensions/super_native_extensions_plugin.h> #include <super_native_extensions/super_native_extensions_plugin.h>
#include <syncfusion_pdfviewer_linux/syncfusion_pdfviewer_linux_plugin.h>
#include <tray_manager/tray_manager_plugin.h> #include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
#include <volume_controller/volume_controller_plugin.h> #include <volume_controller/volume_controller_plugin.h>
@@ -80,6 +81,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) super_native_extensions_registrar = g_autoptr(FlPluginRegistrar) super_native_extensions_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin");
super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar); super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar);
g_autoptr(FlPluginRegistrar) syncfusion_pdfviewer_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SyncfusionPdfviewerLinuxPlugin");
syncfusion_pdfviewer_linux_plugin_register_with_registrar(syncfusion_pdfviewer_linux_registrar);
g_autoptr(FlPluginRegistrar) tray_manager_registrar = g_autoptr(FlPluginRegistrar) tray_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin");
tray_manager_plugin_register_with_registrar(tray_manager_registrar); tray_manager_plugin_register_with_registrar(tray_manager_registrar);

View File

@@ -20,6 +20,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
screen_retriever_linux screen_retriever_linux
sqlite3_flutter_libs sqlite3_flutter_libs
super_native_extensions super_native_extensions
syncfusion_pdfviewer_linux
tray_manager tray_manager
url_launcher_linux url_launcher_linux
volume_controller volume_controller

View File

@@ -39,6 +39,7 @@ import sign_in_with_apple
import sqflite_darwin import sqflite_darwin
import sqlite3_flutter_libs import sqlite3_flutter_libs
import super_native_extensions import super_native_extensions
import syncfusion_pdfviewer_macos
import tray_manager import tray_manager
import url_launcher_macos import url_launcher_macos
import volume_controller import volume_controller
@@ -80,6 +81,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin"))
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin")) TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin")) VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin"))

View File

@@ -2506,6 +2506,78 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.1" version: "0.4.1"
syncfusion_flutter_core:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "6a01bd0da768003f59a9c51ae28145a61372abb59e3e588ef33c86db3579bccf"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_flutter_pdf:
dependency: transitive
description:
name: syncfusion_flutter_pdf
sha256: "5954260288621f1070356b206abeece7f38fcc754cfbf6755f766f356280a0ec"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_flutter_pdfviewer:
dependency: "direct main"
description:
name: syncfusion_flutter_pdfviewer
sha256: "4bb3cdff34fe937430fdd0b5d6488f6a68efa8cfe08c73cc4b19d2a879dde057"
url: "https://pub.dev"
source: hosted
version: "31.1.21"
syncfusion_flutter_signaturepad:
dependency: transitive
description:
name: syncfusion_flutter_signaturepad
sha256: "4b6d7fc679fe1fb2978bd78bd35ca4542c1d4868330687f56177685e5fb19a04"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_pdfviewer_linux:
dependency: transitive
description:
name: syncfusion_pdfviewer_linux
sha256: "8cb32caead6d7d307f39b840d7106796c339667193317a389ca44273b52f6687"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_pdfviewer_macos:
dependency: transitive
description:
name: syncfusion_pdfviewer_macos
sha256: "9bb6c349920ddce69182617875fc1ec8d7788be9bb642ddde5443af4f98b983c"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_pdfviewer_platform_interface:
dependency: transitive
description:
name: syncfusion_pdfviewer_platform_interface
sha256: "25084055ccff99a6ec2378d2fce6b4a8a0fece9fe01bc7ca509aebc9e1f0e3b7"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_pdfviewer_web:
dependency: transitive
description:
name: syncfusion_pdfviewer_web
sha256: "5b60de98f59c9bbfe952c1e7345a35a274a41d61889ea93fa4327e4b0ea12c9a"
url: "https://pub.dev"
source: hosted
version: "31.1.22"
syncfusion_pdfviewer_windows:
dependency: transitive
description:
name: syncfusion_pdfviewer_windows
sha256: f57717111505d48a6e14b42a3ad908e5b0fbfaee03b07803365bc105d49e54d5
url: "https://pub.dev"
source: hosted
version: "31.1.22"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
@@ -2926,4 +2998,4 @@ packages:
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.9.0 <4.0.0" dart: ">=3.9.0 <4.0.0"
flutter: ">=3.35.0" flutter: ">=3.35.1"

View File

@@ -159,6 +159,7 @@ dependencies:
talker_dio_logger: ^5.0.1 talker_dio_logger: ^5.0.1
talker_riverpod_logger: ^5.0.1 talker_riverpod_logger: ^5.0.1
app_links: ^6.4.1 app_links: ^6.4.1
syncfusion_flutter_pdfviewer: ^31.1.21
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@@ -30,6 +30,7 @@
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h> #include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <super_native_extensions/super_native_extensions_plugin_c_api.h> #include <super_native_extensions/super_native_extensions_plugin_c_api.h>
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
#include <tray_manager/tray_manager_plugin.h> #include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <volume_controller/volume_controller_plugin_c_api.h> #include <volume_controller/volume_controller_plugin_c_api.h>
@@ -85,6 +86,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin")); registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin"));
SuperNativeExtensionsPluginCApiRegisterWithRegistrar( SuperNativeExtensionsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi")); registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi"));
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
TrayManagerPluginRegisterWithRegistrar( TrayManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("TrayManagerPlugin")); registry->GetRegistrarForPlugin("TrayManagerPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@@ -27,6 +27,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
share_plus share_plus
sqlite3_flutter_libs sqlite3_flutter_libs
super_native_extensions super_native_extensions
syncfusion_pdfviewer_windows
tray_manager tray_manager
url_launcher_windows url_launcher_windows
volume_controller volume_controller