improvements

This commit is contained in:
Myzel394 2022-08-14 16:38:49 +02:00
parent 83f3ac8674
commit da2d658557
9 changed files with 105 additions and 28 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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(
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,
),
],
);
}

View File

@ -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) {

View File

@ -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();
}
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}');
}

View File

@ -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,14 +65,40 @@ 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(
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(
top: LARGE_SPACE, left: MEDIUM_SPACE, right: MEDIUM_SPACE),

View File

@ -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: () {

View File

@ -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"

View File

@ -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: