feat(mobile): more info for asset viewer
parent
92f8ffe722
commit
3efbda859b
|
|
@ -1286,6 +1286,7 @@
|
||||||
"link_to_oauth": "Link to OAuth",
|
"link_to_oauth": "Link to OAuth",
|
||||||
"linked_oauth_account": "Linked OAuth account",
|
"linked_oauth_account": "Linked OAuth account",
|
||||||
"list": "List",
|
"list": "List",
|
||||||
|
"live": "Live",
|
||||||
"loading": "Loading",
|
"loading": "Loading",
|
||||||
"loading_search_results_failed": "Loading search results failed",
|
"loading_search_results_failed": "Loading search results failed",
|
||||||
"local": "Local",
|
"local": "Local",
|
||||||
|
|
@ -1415,6 +1416,7 @@
|
||||||
"month": "Month",
|
"month": "Month",
|
||||||
"monthly_title_text_date_format": "MMMM y",
|
"monthly_title_text_date_format": "MMMM y",
|
||||||
"more": "More",
|
"more": "More",
|
||||||
|
"motion": "Motion",
|
||||||
"move": "Move",
|
"move": "Move",
|
||||||
"move_off_locked_folder": "Move out of locked folder",
|
"move_off_locked_folder": "Move out of locked folder",
|
||||||
"move_to": "Move to",
|
"move_to": "Move to",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.widg
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_bar.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_bar.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/motion_photo_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/top_app_bar.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/top_app_bar.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
||||||
|
|
@ -692,6 +693,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||||
backgroundDecoration: BoxDecoration(color: backgroundColor),
|
backgroundDecoration: BoxDecoration(color: backgroundColor),
|
||||||
enablePanAlways: true,
|
enablePanAlways: true,
|
||||||
),
|
),
|
||||||
|
const Positioned(top: -40, left: 0, right: 0, child: MotionPhotoPlayButton()),
|
||||||
if (!showingBottomSheet)
|
if (!showingBottomSheet)
|
||||||
const Positioned(
|
const Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/extensions/platform_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
|
||||||
|
|
||||||
|
class MotionPhotoPlayButton extends ConsumerWidget {
|
||||||
|
const MotionPhotoPlayButton({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final asset = ref.watch(currentAssetNotifier);
|
||||||
|
final isPlaying = ref.watch(isPlayingMotionVideoProvider);
|
||||||
|
final showControls = ref.watch(assetViewerProvider.select((state) => state.showingControls));
|
||||||
|
final isShowingSheet = ref.watch(assetViewerProvider.select((state) => state.showingBottomSheet));
|
||||||
|
|
||||||
|
if (asset == null || !asset.isMotionPhoto || isShowingSheet) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return IgnorePointer(
|
||||||
|
ignoring: !showControls,
|
||||||
|
child: AnimatedOpacity(
|
||||||
|
opacity: showControls ? 1.0 : 0.0,
|
||||||
|
duration: Durations.short2,
|
||||||
|
child: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 60),
|
||||||
|
child: Center(
|
||||||
|
child: _MotionButton(
|
||||||
|
isPlaying: isPlaying,
|
||||||
|
onPressed: ref.read(isPlayingMotionVideoProvider.notifier).toggle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MotionButton extends StatelessWidget {
|
||||||
|
final bool isPlaying;
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
|
const _MotionButton({required this.isPlaying, required this.onPressed});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.grey[800]!.withValues(alpha: 0.4),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(24)),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onPressed,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(24)),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
isPlaying ? Icons.motion_photos_pause_outlined : Icons.play_circle_outline_rounded,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
CurrentPlatform.isAndroid ? 'motion'.t(context: context) : 'live'.t(context: context),
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ import 'package:immich_mobile/domain/models/events.model.dart';
|
||||||
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/favorite_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/favorite_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart';
|
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart';
|
||||||
|
|
@ -51,7 +50,6 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
||||||
final originalTheme = context.themeData;
|
final originalTheme = context.themeData;
|
||||||
|
|
||||||
final actions = <Widget>[
|
final actions = <Widget>[
|
||||||
if (asset.isMotionPhoto) const MotionPhotoActionButton(iconOnly: true),
|
|
||||||
if (album != null && album.isActivityEnabled && album.isShared)
|
if (album != null && album.isActivityEnabled && album.isShared)
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.chat_outlined),
|
icon: const Icon(Icons.chat_outlined),
|
||||||
|
|
@ -132,7 +130,10 @@ class _AssetInfoTitle extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final dateTime = asset.createdAt.toLocal();
|
final dateTime = asset.createdAt.toLocal();
|
||||||
final dateFormatted = DateFormat.yMMMd().format(dateTime);
|
final currentYear = DateTime.now().year;
|
||||||
|
final isCurrentYear = dateTime.year == currentYear;
|
||||||
|
|
||||||
|
final dateFormatted = isCurrentYear ? DateFormat.MMMd().format(dateTime) : DateFormat.yMMMd().format(dateTime);
|
||||||
final timeFormatted = DateFormat.jm().format(dateTime);
|
final timeFormatted = DateFormat.jm().format(dateTime);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue