mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-18 23:35:25 +02:00
improvements
This commit is contained in:
parent
83f3ac8674
commit
da2d658557
@ -1,3 +1,5 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:property_change_notifier/property_change_notifier.dart';
|
||||
|
||||
class MemorySlideController extends PropertyChangeNotifier<String> {
|
||||
@ -39,6 +41,11 @@ class MemorySlideController extends PropertyChangeNotifier<String> {
|
||||
}
|
||||
}
|
||||
|
||||
void previous() {
|
||||
_index = max(_index - 1, 0);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_completed = false;
|
||||
_paused = false;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:path/path.dart';
|
||||
import 'package:share_location/enums.dart';
|
||||
|
||||
class Memory {
|
||||
@ -25,6 +26,8 @@ class Memory {
|
||||
);
|
||||
}
|
||||
|
||||
String get filename => basename(location);
|
||||
|
||||
MemoryType get type =>
|
||||
location.split('.').last == 'jpg' ? MemoryType.photo : MemoryType.video;
|
||||
filename.split('.').last == 'jpg' ? MemoryType.photo : MemoryType.video;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:share_location/constants/spacing.dart';
|
||||
@ -20,6 +21,7 @@ enum MemoryFetchStatus {
|
||||
class MemoryView extends StatefulWidget {
|
||||
final String location;
|
||||
final DateTime creationDate;
|
||||
final String filename;
|
||||
final bool loopVideo;
|
||||
final void Function(VideoPlayerController)? onVideoControllerInitialized;
|
||||
final VoidCallback? onFileDownloaded;
|
||||
@ -28,6 +30,7 @@ class MemoryView extends StatefulWidget {
|
||||
Key? key,
|
||||
required this.location,
|
||||
required this.creationDate,
|
||||
required this.filename,
|
||||
this.loopVideo = false,
|
||||
this.onVideoControllerInitialized,
|
||||
this.onFileDownloaded,
|
||||
@ -131,11 +134,30 @@ class _MemoryViewState extends AuthRequiredState<MemoryView> {
|
||||
}
|
||||
|
||||
if (status == MemoryFetchStatus.done) {
|
||||
return RawMemoryDisplay(
|
||||
data: data!,
|
||||
type: type!,
|
||||
loopVideo: widget.loopVideo,
|
||||
onVideoControllerInitialized: widget.onVideoControllerInitialized,
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
if (type == MemoryType.photo)
|
||||
ImageFiltered(
|
||||
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||
child: RawMemoryDisplay(
|
||||
filename: widget.filename,
|
||||
data: data!,
|
||||
type: type!,
|
||||
loopVideo: widget.loopVideo,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
RawMemoryDisplay(
|
||||
filename: widget.filename,
|
||||
data: data!,
|
||||
type: type!,
|
||||
fit: BoxFit.contain,
|
||||
loopVideo: widget.loopVideo,
|
||||
onVideoControllerInitialized: widget.onVideoControllerInitialized,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ class _MemorySlideState extends State<MemorySlide>
|
||||
child: MemoryView(
|
||||
creationDate: widget.memory.creationDate,
|
||||
location: widget.memory.location,
|
||||
filename: widget.memory.filename,
|
||||
loopVideo: false,
|
||||
onFileDownloaded: () {
|
||||
if (widget.memory.type == MemoryType.photo) {
|
||||
|
@ -12,12 +12,14 @@ class RawMemoryDisplay extends StatefulWidget {
|
||||
final bool loopVideo;
|
||||
final String? filename;
|
||||
final void Function(VideoPlayerController)? onVideoControllerInitialized;
|
||||
final BoxFit? fit;
|
||||
|
||||
const RawMemoryDisplay({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required this.type,
|
||||
this.loopVideo = false,
|
||||
this.fit = BoxFit.cover,
|
||||
this.filename,
|
||||
this.onVideoControllerInitialized,
|
||||
}) : super(key: key);
|
||||
@ -41,14 +43,15 @@ class _RawMemoryDisplayState extends State<RawMemoryDisplay> {
|
||||
Future<File> createTempVideo() async {
|
||||
final tempDirectory = await getTemporaryDirectory();
|
||||
final path = '${tempDirectory.path}/${widget.filename ?? 'video.mp4'}';
|
||||
final file = File(path);
|
||||
|
||||
if (widget.filename != null) {
|
||||
// File already exists, so just return the path
|
||||
return File(path);
|
||||
if (await file.exists()) {
|
||||
// File already exists, so just return it
|
||||
return file;
|
||||
}
|
||||
|
||||
// File needs to be created
|
||||
final file = await File(path).create();
|
||||
await file.create();
|
||||
await file.writeAsBytes(widget.data);
|
||||
|
||||
return file;
|
||||
@ -82,17 +85,27 @@ class _RawMemoryDisplayState extends State<RawMemoryDisplay> {
|
||||
case MemoryType.photo:
|
||||
return Image.memory(
|
||||
widget.data,
|
||||
fit: BoxFit.cover,
|
||||
fit: widget.fit,
|
||||
);
|
||||
case MemoryType.video:
|
||||
if (videoController == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return AspectRatio(
|
||||
aspectRatio: videoController!.value.aspectRatio,
|
||||
child: VideoPlayer(videoController!),
|
||||
);
|
||||
switch (widget.fit) {
|
||||
case BoxFit.contain:
|
||||
return Align(
|
||||
child: AspectRatio(
|
||||
aspectRatio: videoController!.value.aspectRatio,
|
||||
child: VideoPlayer(videoController!),
|
||||
),
|
||||
);
|
||||
default:
|
||||
return AspectRatio(
|
||||
aspectRatio: videoController!.value.aspectRatio,
|
||||
child: VideoPlayer(videoController!),
|
||||
);
|
||||
}
|
||||
default:
|
||||
throw Exception('Unknown memory type: ${widget.type}');
|
||||
}
|
||||
|
@ -5,13 +5,13 @@ import 'package:share_location/controllers/memory_slide_controller.dart';
|
||||
import 'package:share_location/foreign_types/memory.dart';
|
||||
import 'package:share_location/widgets/memory_slide.dart';
|
||||
|
||||
class MemoryPage extends StatefulWidget {
|
||||
class TimelinePage extends StatefulWidget {
|
||||
final DateTime date;
|
||||
final List<Memory> memories;
|
||||
final VoidCallback onPreviousTimeline;
|
||||
final VoidCallback onNextTimeline;
|
||||
|
||||
const MemoryPage({
|
||||
const TimelinePage({
|
||||
Key? key,
|
||||
required this.date,
|
||||
required this.memories,
|
||||
@ -20,10 +20,11 @@ class MemoryPage extends StatefulWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MemoryPage> createState() => _MemoryPageState();
|
||||
State<TimelinePage> createState() => _TimelinePageState();
|
||||
}
|
||||
|
||||
class _MemoryPageState extends State<MemoryPage> {
|
||||
class _TimelinePageState extends State<TimelinePage> {
|
||||
final pageController = PageController();
|
||||
late final MemorySlideController controller;
|
||||
|
||||
@override
|
||||
@ -34,8 +35,11 @@ class _MemoryPageState extends State<MemoryPage> {
|
||||
controller.addListener(() {
|
||||
if (controller.done) {
|
||||
controller.next();
|
||||
// Force UI update
|
||||
setState(() {});
|
||||
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.linearToEaseOut,
|
||||
);
|
||||
}
|
||||
}, ['done']);
|
||||
controller.addListener(() {
|
||||
@ -61,13 +65,39 @@ class _MemoryPageState extends State<MemoryPage> {
|
||||
onTapUp: (_) {
|
||||
controller.setPaused(false);
|
||||
},
|
||||
onTapCancel: () {
|
||||
controller.setPaused(false);
|
||||
},
|
||||
onHorizontalDragEnd: (details) {
|
||||
if (details.primaryVelocity! < 0) {
|
||||
controller.next();
|
||||
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.linearToEaseOut,
|
||||
);
|
||||
} else if (details.primaryVelocity! > 0) {
|
||||
controller.previous();
|
||||
|
||||
pageController.previousPage(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.linearToEaseOut,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
MemorySlide(
|
||||
key: Key(controller.index.toString()),
|
||||
controller: controller,
|
||||
memory: widget.memories[controller.index],
|
||||
PageView.builder(
|
||||
controller: pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (_, __) => MemorySlide(
|
||||
key: Key(controller.index.toString()),
|
||||
controller: controller,
|
||||
memory: widget.memories[controller.index],
|
||||
),
|
||||
itemCount: widget.memories.length,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:share_location/foreign_types/memory.dart';
|
||||
import 'package:share_location/utils/loadable.dart';
|
||||
import 'package:share_location/widgets/memory_page.dart';
|
||||
import 'package:share_location/widgets/timeline_page.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
final supabase = Supabase.instance.client;
|
||||
@ -71,7 +71,7 @@ class _TimelineScrollState extends State<TimelineScroll> with Loadable {
|
||||
controller: pageController,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemCount: timeline.length,
|
||||
itemBuilder: (_, index) => MemoryPage(
|
||||
itemBuilder: (_, index) => TimelinePage(
|
||||
date: DateTime.parse(timeline.keys.toList()[index]),
|
||||
memories: timeline.values.toList()[index],
|
||||
onNextTimeline: () {
|
||||
|
@ -311,7 +311,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
path:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -44,6 +44,7 @@ dependencies:
|
||||
path_provider: ^2.0.11
|
||||
intl: ^0.17.0
|
||||
property_change_notifier: ^0.3.0
|
||||
path: ^1.8.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Loading…
x
Reference in New Issue
Block a user