Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ if (keystorePropertiesFile.exists()) {
}

android {
packaging {
jniLibs.pickFirsts.add("lib/**/libc++_shared.so")
}

namespace = "com.remi.piwigo_ng"
//compileSdkVersion flutter.compileSdkVersion
//ndkVersion = flutter.ndkVersion
Expand Down Expand Up @@ -65,6 +69,15 @@ android {

buildTypes {
release {
// Compress libs
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)

signingConfig = signingConfigs.getByName("release")
}
}
Expand Down
1 change: 1 addition & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-keep class org.videolan.libvlc.** { *; }
6 changes: 3 additions & 3 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import 'package:piwigo_ng/views/image/image_favorites_page.dart';
import 'package:piwigo_ng/views/image/image_page.dart';
import 'package:piwigo_ng/views/image/image_search_page.dart';
import 'package:piwigo_ng/views/image/image_tags_page.dart';
import 'package:piwigo_ng/views/image/video_player_page.dart';
import 'package:piwigo_ng/views/image/vlc_video_player.dart';
import 'package:piwigo_ng/views/settings/auto_upload_page.dart';
import 'package:piwigo_ng/views/settings/privacy_policy_page.dart';
import 'package:piwigo_ng/views/settings/select_language_page.dart';
Expand Down Expand Up @@ -192,9 +192,9 @@ Route<dynamic> generateRoute(RouteSettings settings) {
),
settings: settings,
);
case VideoPlayerPage.routeName:
case VlcVideoPlayer.routeName:
return MaterialPageRoute(
builder: (_) => VideoPlayerPage(
builder: (_) => VlcVideoPlayer(
videoUrl: arguments['videoUrl'],
thumbnailUrl: arguments['thumbnailUrl'],
),
Expand Down
111 changes: 53 additions & 58 deletions lib/components/cards/image_details_card.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui show Image;

import 'package:auto_size_text/auto_size_text.dart';
Expand All @@ -14,10 +15,11 @@ import 'package:piwigo_ng/services/preferences_service.dart';
import 'package:piwigo_ng/utils/resources.dart';
import 'package:piwigo_ng/utils/settings.dart';
import 'package:provider/provider.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter_video_thumbnail_plus/flutter_video_thumbnail_plus.dart';

class ImageDetailsCard extends StatelessWidget {
const ImageDetailsCard({Key? key, required this.image, this.onRemove}) : super(key: key);
const ImageDetailsCard({Key? key, required this.image, this.onRemove})
: super(key: key);

final ImageModel image;
final Function()? onRemove;
Expand Down Expand Up @@ -56,7 +58,9 @@ class ImageDetailsCard extends StatelessWidget {
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Builder(builder: (context) {
final String? imageUrl = image.getDerivativeFromString(Preferences.getImageThumbnailSize)?.url;
final String? imageUrl = image
.getDerivativeFromString(Preferences.getImageThumbnailSize)
?.url;
return ImageNetworkDisplay(
imageUrl: imageUrl,
);
Expand Down Expand Up @@ -88,7 +92,10 @@ class ImageDetailsCard extends StatelessWidget {
children: [
Flexible(
child: Text(
image.file.replaceAll('', '\u200B').split(path.extension(image.file)).first,
image.file
.replaceAll('', '\u200B')
.split(path.extension(image.file))
.first,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall,
Expand All @@ -106,11 +113,13 @@ class ImageDetailsCard extends StatelessWidget {
const Spacer(),
if (image.dateAvailable != null)
Builder(builder: (context) {
LocaleNotifier localeNotifier = Provider.of<LocaleNotifier>(context, listen: false);
LocaleNotifier localeNotifier =
Provider.of<LocaleNotifier>(context, listen: false);
String date =
DateFormat.yMMMMd(localeNotifier.locale.languageCode).format(DateTime.parse(image.dateAvailable!));
String time =
DateFormat.Hms(localeNotifier.locale.languageCode).format(DateTime.parse(image.dateAvailable!));
DateFormat.yMMMMd(localeNotifier.locale.languageCode)
.format(DateTime.parse(image.dateAvailable!));
String time = DateFormat.Hms(localeNotifier.locale.languageCode)
.format(DateTime.parse(image.dateAvailable!));
return AutoSizeText(
"$date $time",
maxLines: 1,
Expand Down Expand Up @@ -142,7 +151,8 @@ class ImageDetailsCard extends StatelessWidget {
}

class LocalImageDetailsCard extends StatefulWidget {
const LocalImageDetailsCard({Key? key, required this.image, this.onRemove, this.isDuplicate = false})
const LocalImageDetailsCard(
{Key? key, required this.image, this.onRemove, this.isDuplicate = false})
: super(key: key);

final File image;
Expand Down Expand Up @@ -205,12 +215,17 @@ class _LocalImageDetailsCardState extends State<LocalImageDetailsCard> {
fit: StackFit.expand,
children: [
LayoutBuilder(builder: (context, constraints) {
List<String>? mimeType = mime(widget.image.path.split('/').last)?.split('/');
List<String>? mimeType =
mime(widget.image.path.split('/').last)?.split('/');

if (mimeType?.first == 'image') {
_checkMemory();
double? cacheWidth = constraints.maxWidth.isInfinite ? constraints.maxWidth : null;
double? cacheHeight = constraints.maxHeight.isInfinite ? constraints.maxHeight : null;
double? cacheWidth = constraints.maxWidth.isInfinite
? constraints.maxWidth
: null;
double? cacheHeight = constraints.maxHeight.isInfinite
? constraints.maxHeight
: null;
return Image.file(
widget.image,
fit: BoxFit.cover,
Expand Down Expand Up @@ -313,7 +328,8 @@ class _LocalImageDetailsCardState extends State<LocalImageDetailsCard> {
}

class LocalVideoDetailsCard extends StatefulWidget {
const LocalVideoDetailsCard({Key? key, required this.video, this.onRemove, this.isDuplicate = false})
const LocalVideoDetailsCard(
{Key? key, required this.video, this.onRemove, this.isDuplicate = false})
: super(key: key);

final File video;
Expand All @@ -325,31 +341,28 @@ class LocalVideoDetailsCard extends StatefulWidget {
}

class _LocalVideoDetailsCardState extends State<LocalVideoDetailsCard> {
late final VideoPlayerController _controller;
late Image thumbnail;

@override
void initState() {
_controller = VideoPlayerController.file(
File(widget.video.path),
videoPlayerOptions: VideoPlayerOptions(),
)..initialize().then((_) => setState(() {}));
WidgetsBinding.instance.addPostFrameCallback((_) async {
thumbnail =Image.memory(Uint8List(0));
thumbnail = Image.memory(await FlutterVideoThumbnailPlus.thumbnailData(
video: widget.video.path) ??
([] as Uint8List));
});
super.initState();
}

Future<void> getThumbnail() async {
setState(() {});
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

String get _duration {
final Duration duration = _controller.value.duration;
int hours = duration.inHours;
int minutes = (duration - Duration(hours: hours)).inMinutes;
int seconds = (duration - Duration(hours: hours) - Duration(minutes: minutes)).inSeconds;
return '${hours > 0 ? '$hours:' : ''}${minutes < 10 ? '0$minutes' : '$minutes'}:${seconds < 10 ? '0$seconds' : '$seconds'}';
}

@override
Widget build(BuildContext context) {
return Stack(
Expand Down Expand Up @@ -385,16 +398,6 @@ class _LocalVideoDetailsCardState extends State<LocalVideoDetailsCard> {
fit: StackFit.expand,
children: [
LayoutBuilder(builder: (context, constraints) {
if (_controller.value.hasError) {
return Center(
child: Icon(Icons.image_not_supported),
);
}
if (!_controller.value.isInitialized) {
return Center(
child: CircularProgressIndicator(),
);
}
return Stack(
alignment: Alignment.center,
fit: StackFit.expand,
Expand All @@ -403,25 +406,27 @@ class _LocalVideoDetailsCardState extends State<LocalVideoDetailsCard> {
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: _controller.value.size.width,
height: _controller.value.size.height,
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
width: thumbnail.width,
height: thumbnail.height,
child: thumbnail,
),
),
),
Positioned(
bottom: 2.0,
left: 2.0,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
padding: const EdgeInsets.symmetric(
horizontal: 4, vertical: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), color: AppColors.black.withValues(alpha: 0.7)),
borderRadius: BorderRadius.circular(5),
color: AppColors.black.withValues(alpha: 0.7)),
child: Text(
_duration,
style: TextStyle(color: AppColors.white, fontSize: 10, fontWeight: FontWeight.bold),
"duration",
style: TextStyle(
color: AppColors.white,
fontSize: 10,
fontWeight: FontWeight.bold),
),
),
),
Expand Down Expand Up @@ -452,21 +457,11 @@ class _LocalVideoDetailsCardState extends State<LocalVideoDetailsCard> {
),
child: Builder(
builder: (context) {
if (_controller.value.hasError) {
return Center(
child: Icon(Icons.image_not_supported),
);
}
if (!_controller.value.isInitialized) {
return Center(
child: CircularProgressIndicator(),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"${_controller.value.size.width.round()}x${_controller.value.size.height.round()} pixels",
"${thumbnail.width}x${thumbnail.height} pixels",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall,
Expand Down
1 change: 0 additions & 1 deletion lib/components/modals/select_move_or_copy_modal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:piwigo_ng/models/album_model.dart';
import 'package:piwigo_ng/network/albums.dart';
import 'package:piwigo_ng/network/api_error.dart';
import 'package:piwigo_ng/utils/localizations.dart';
import 'package:piwigo_ng/utils/resources.dart';

class SelectMoveOrCopyModal extends StatefulWidget {
const SelectMoveOrCopyModal({
Expand Down
Loading