Add QoL feed, download and quality improvements
This commit is contained in:
@@ -84,6 +84,8 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
final next = currentIndex >= 0 && currentIndex < feedPosts.length - 1
|
||||
? feedPosts[currentIndex + 1]
|
||||
: null;
|
||||
final qualityMode =
|
||||
MediaQualityMode.fromName(settings.mediaQualityMode);
|
||||
if (Responsive.isMobile(context)) {
|
||||
if (currentIndex >= 0 && feedPosts.length > 1) {
|
||||
return _MobilePostPager(
|
||||
@@ -95,6 +97,7 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
post,
|
||||
settings,
|
||||
favoriteKeys,
|
||||
qualityMode,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -104,6 +107,7 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
post,
|
||||
settings,
|
||||
favoriteKeys,
|
||||
qualityMode,
|
||||
);
|
||||
}
|
||||
return Shortcuts(
|
||||
@@ -116,6 +120,7 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
const _ToggleFavoriteIntent(),
|
||||
LogicalKeySet(LogicalKeyboardKey.keyC):
|
||||
const _AddCollectionIntent(),
|
||||
LogicalKeySet(LogicalKeyboardKey.keyS): const _DownloadIntent(),
|
||||
LogicalKeySet(LogicalKeyboardKey.escape): const _CloseIntent(),
|
||||
},
|
||||
child: Actions(
|
||||
@@ -150,6 +155,14 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
_DownloadIntent: CallbackAction<_DownloadIntent>(
|
||||
onInvoke: (_) {
|
||||
if (settings.allowDownloads) {
|
||||
_download(context, ref, post);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
},
|
||||
child: Focus(
|
||||
autofocus: true,
|
||||
@@ -170,7 +183,10 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
child: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 760),
|
||||
child: PostMediaViewer(post: post),
|
||||
child: PostMediaViewer(
|
||||
post: post,
|
||||
qualityMode: qualityMode,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -243,6 +259,7 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
Post post,
|
||||
AppSettings settings,
|
||||
Set<String> favoriteKeys,
|
||||
MediaQualityMode qualityMode,
|
||||
) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 16),
|
||||
@@ -251,7 +268,12 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.sizeOf(context).height * 0.62,
|
||||
),
|
||||
child: Center(child: PostMediaViewer(post: post)),
|
||||
child: Center(
|
||||
child: PostMediaViewer(
|
||||
post: post,
|
||||
qualityMode: qualityMode,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
PostActionBar(
|
||||
@@ -319,22 +341,12 @@ class PostDetailsScreen extends ConsumerWidget {
|
||||
}
|
||||
|
||||
Future<void> _download(BuildContext context, WidgetRef ref, Post post) async {
|
||||
if (!context.mounted) return;
|
||||
await ref.read(downloadManagerServiceProvider).start(post);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Downloading...')),
|
||||
const SnackBar(content: Text('Download started')),
|
||||
);
|
||||
try {
|
||||
final saved = await ref.read(downloadServiceProvider).downloadPost(post);
|
||||
if (!context.mounted || saved == null) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Download complete: $saved')),
|
||||
);
|
||||
} catch (error) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Download failed: $error')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _toggleFavorite(
|
||||
@@ -583,6 +595,10 @@ class _CloseIntent extends Intent {
|
||||
const _CloseIntent();
|
||||
}
|
||||
|
||||
class _DownloadIntent extends Intent {
|
||||
const _DownloadIntent();
|
||||
}
|
||||
|
||||
class _CommentsSection extends ConsumerStatefulWidget {
|
||||
const _CommentsSection({required this.post});
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ class PostMediaViewer extends StatefulWidget {
|
||||
this.initialMuted = false,
|
||||
this.initialCoverVideo = false,
|
||||
this.initialHalfVolume = false,
|
||||
this.qualityMode = MediaQualityMode.auto,
|
||||
this.onPlaybackSnapshot,
|
||||
super.key,
|
||||
});
|
||||
@@ -36,6 +37,7 @@ class PostMediaViewer extends StatefulWidget {
|
||||
final bool initialMuted;
|
||||
final bool initialCoverVideo;
|
||||
final bool initialHalfVolume;
|
||||
final MediaQualityMode qualityMode;
|
||||
final ValueChanged<VideoPlaybackSnapshot>? onPlaybackSnapshot;
|
||||
|
||||
@override
|
||||
@@ -281,18 +283,11 @@ class _PostMediaViewerState extends State<PostMediaViewer> {
|
||||
}
|
||||
|
||||
List<String> _buildImageUrls(Post post) {
|
||||
final urls = post.fileType.toLowerCase().contains('gif')
|
||||
? [post.fileUrl, post.sampleUrl, post.previewUrl]
|
||||
: [post.sampleUrl, post.fileUrl, post.previewUrl];
|
||||
return urls.where((url) => url.trim().isNotEmpty).toSet().toList();
|
||||
return MediaUrlSelector.details(post, mode: widget.qualityMode);
|
||||
}
|
||||
|
||||
List<String> _buildVideoUrls(Post post) {
|
||||
return {
|
||||
post.fileUrl,
|
||||
if (_looksLikeVideoUrl(post.sampleUrl)) post.sampleUrl,
|
||||
if (_looksLikeVideoUrl(post.previewUrl)) post.previewUrl,
|
||||
}.where((url) => url.trim().isNotEmpty).toList();
|
||||
return MediaUrlSelector.video(post);
|
||||
}
|
||||
|
||||
bool _isVideo(Post post) {
|
||||
@@ -318,13 +313,6 @@ class _PostMediaViewerState extends State<PostMediaViewer> {
|
||||
return post.fileUrl.trim();
|
||||
}
|
||||
|
||||
bool _looksLikeVideoUrl(String url) {
|
||||
final value = url.toLowerCase();
|
||||
return value.contains('.webm') ||
|
||||
value.contains('.mp4') ||
|
||||
value.contains('.mov');
|
||||
}
|
||||
|
||||
Map<String, String> _headersFor(Post post) {
|
||||
return {
|
||||
'User-Agent': 'RuleGel/0.2 Flutter local booru browser',
|
||||
@@ -796,6 +784,7 @@ class _FullscreenVideoPageState extends State<_FullscreenVideoPage> {
|
||||
initialMuted: widget.muted,
|
||||
initialHalfVolume: widget.halfVolume,
|
||||
initialCoverVideo: widget.coverVideo,
|
||||
qualityMode: MediaQualityMode.highQuality,
|
||||
onPlaybackSnapshot: (snapshot) => _snapshot = snapshot,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user