Compare commits
3 Commits
v1.0.20+20
...
v1.0.22+22
Author | SHA1 | Date | |
---|---|---|---|
c236049c0a | |||
003797981e | |||
1120787f4a |
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:f0ckapp/mediagrid.dart';
|
||||
import 'package:f0ckapp/screens/MediaGrid.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -1,8 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:f0ckapp/models/mediaitem.dart';
|
||||
import 'package:f0ckapp/services/api.dart';
|
||||
import 'package:f0ckapp/widgets/video_widget.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:f0ckapp/models/MediaItem.dart';
|
||||
import 'package:f0ckapp/services/Api.dart';
|
||||
import 'package:f0ckapp/widgets/VideoWidget.dart';
|
||||
import 'package:f0ckapp/utils/SmartRefreshIndicator.dart';
|
||||
import 'package:f0ckapp/utils/PageTransformer.dart';
|
||||
|
||||
class DetailView extends StatefulWidget {
|
||||
final int initialItemId;
|
||||
@ -108,20 +110,18 @@ class _DetailViewState extends State<DetailView> {
|
||||
title: Text('f0ck #$currentItemId (${widget.type})'),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: PageView.builder(
|
||||
body: PageTransformer(
|
||||
controller: _pageController,
|
||||
itemCount: mediaItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
final MediaItem item = mediaItems[index];
|
||||
pages: mediaItems.map((item) {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: SmartRefreshIndicator(
|
||||
onRefresh: _refreshMediaItem,
|
||||
child: _buildMediaItem(item)
|
||||
child: _buildMediaItem(item),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -129,11 +129,14 @@ class _DetailViewState extends State<DetailView> {
|
||||
Widget _buildMediaItem(MediaItem item) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (item.mime.startsWith('image'))
|
||||
Image.network(
|
||||
item.mediaUrl,
|
||||
CachedNetworkImage(
|
||||
imageUrl: item.mediaUrl,
|
||||
fit: BoxFit.contain,
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
)
|
||||
else
|
||||
VideoWidget(details: item),
|
||||
@ -142,7 +145,7 @@ class _DetailViewState extends State<DetailView> {
|
||||
item.mime,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 18),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const SizedBox(height: 10, width: double.infinity),
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 5.0,
|
||||
@ -152,7 +155,7 @@ class _DetailViewState extends State<DetailView> {
|
||||
backgroundColor: switch (tag.id) {
|
||||
1 => Colors.green,
|
||||
2 => Colors.red,
|
||||
_ => const Color(0xFF090909)
|
||||
_ => const Color(0xFF090909),
|
||||
},
|
||||
labelStyle: const TextStyle(color: Colors.white),
|
||||
);
|
@ -1,7 +1,8 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:f0ckapp/services/api.dart';
|
||||
import 'package:f0ckapp/models/mediaitem.dart';
|
||||
import 'package:f0ckapp/screens/detailview.dart';
|
||||
import 'package:f0ckapp/services/Api.dart';
|
||||
import 'package:f0ckapp/models/MediaItem.dart';
|
||||
import 'package:f0ckapp/screens/DetailView.dart';
|
||||
import 'dart:async';
|
||||
|
||||
class MediaGrid extends StatefulWidget {
|
||||
@ -13,7 +14,7 @@ class MediaGrid extends StatefulWidget {
|
||||
|
||||
class _MediaGridState extends State<MediaGrid> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
final String _version = '1.0.20+20';
|
||||
final String _version = '1.0.22+22';
|
||||
List<MediaItem> mediaItems = [];
|
||||
bool isLoading = false;
|
||||
Timer? _debounceTimer;
|
||||
@ -243,18 +244,28 @@ class _MediaGridState extends State<MediaGrid> {
|
||||
}
|
||||
final item = mediaItems[index];
|
||||
|
||||
final mode =
|
||||
{1: Colors.green, 2: Colors.red}[item.mode] ?? Colors.yellow;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => _navigateToDetail(item),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Image.network(item.thumbnailUrl, fit: BoxFit.cover),
|
||||
CachedNetworkImage(
|
||||
imageUrl: item.thumbnailUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => SizedBox.shrink(),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
),
|
||||
Align(
|
||||
alignment: FractionalOffset.bottomRight,
|
||||
child: Icon(Icons.square, color: mode, size: 15.0),
|
||||
child: Icon(
|
||||
Icons.square,
|
||||
color: switch (item.mode) {
|
||||
1 => Colors.green,
|
||||
2 => Colors.red,
|
||||
_ => Colors.yellow
|
||||
},
|
||||
size: 15.0
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:f0ckapp/models/mediaitem.dart';
|
||||
import 'package:f0ckapp/models/MediaItem.dart';
|
||||
|
||||
Future<List<MediaItem>> fetchMedia({
|
||||
String? older,
|
42
lib/utils/PageTransformer.dart
Normal file
42
lib/utils/PageTransformer.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PageTransformer extends StatelessWidget {
|
||||
final List<Widget> pages;
|
||||
final PageController controller;
|
||||
|
||||
const PageTransformer({
|
||||
super.key,
|
||||
required this.pages,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PageView.builder(
|
||||
controller: controller,
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildPage(pages[index], index);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPage(Widget page, int index) {
|
||||
return AnimatedBuilder(
|
||||
animation: controller,
|
||||
builder: (context, child) {
|
||||
double value = 1.0;
|
||||
if (controller.position.haveDimensions) {
|
||||
value = controller.page! - index;
|
||||
value = (1 - (value.abs() * 0.5)).clamp(0.0, 1.0);
|
||||
}
|
||||
return Transform(
|
||||
transform: Matrix4.identity()..scale(value, value),
|
||||
alignment: Alignment.center,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: page,
|
||||
);
|
||||
}
|
||||
}
|
134
lib/widgets/VideoOverlay.dart
Normal file
134
lib/widgets/VideoOverlay.dart
Normal file
@ -0,0 +1,134 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class VideoControlsOverlay extends StatelessWidget {
|
||||
final VideoPlayerController controller;
|
||||
final VoidCallback button;
|
||||
|
||||
const VideoControlsOverlay({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.button,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_ControlButton(Icons.replay_10, () {
|
||||
button();
|
||||
controller.seekTo(
|
||||
controller.value.position - Duration(seconds: 10),
|
||||
);
|
||||
}),
|
||||
SizedBox(width: 40),
|
||||
_ControlButton(
|
||||
controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
|
||||
() {
|
||||
button();
|
||||
controller.value.isPlaying
|
||||
? controller.pause()
|
||||
: controller.play();
|
||||
},
|
||||
size: 64,
|
||||
),
|
||||
SizedBox(width: 40),
|
||||
_ControlButton(Icons.forward_10, () {
|
||||
button();
|
||||
controller.seekTo(
|
||||
controller.value.position + Duration(seconds: 10),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
_ProgressIndicator(controller: controller)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ControlButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final VoidCallback onPressed;
|
||||
final double size;
|
||||
|
||||
const _ControlButton(this.icon, this.onPressed, {this.size = 24});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.black.withValues(alpha: 0.4),
|
||||
),
|
||||
child: IconButton(
|
||||
icon: Icon(icon, color: Colors.white, size: size),
|
||||
onPressed: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressIndicator extends StatelessWidget {
|
||||
final VideoPlayerController controller;
|
||||
|
||||
const _ProgressIndicator({required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
VideoProgressIndicator(
|
||||
controller,
|
||||
allowScrubbing: true,
|
||||
padding: const EdgeInsets.only(top: 25.0),
|
||||
colors: VideoProgressColors(
|
||||
playedColor: Colors.red,
|
||||
backgroundColor: Colors.grey,
|
||||
bufferedColor: Colors.white54,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left:
|
||||
(controller.value.position.inMilliseconds /
|
||||
controller.value.duration.inMilliseconds) *
|
||||
MediaQuery.of(context).size.width -
|
||||
6,
|
||||
bottom: -4,
|
||||
child: Container(
|
||||
width: 12,
|
||||
height: 12,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
border: Border.all(color: Colors.red, width: 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 16,
|
||||
bottom: 10,
|
||||
child: Text(
|
||||
'${_formatDuration(controller.value.position)} / ${_formatDuration(controller.value.duration)}',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDuration(Duration duration) {
|
||||
String twoDigits(int n) => n.toString().padLeft(2, '0');
|
||||
return "${twoDigits(duration.inMinutes % 60)}:${twoDigits(duration.inSeconds % 60)}";
|
||||
}
|
||||
}
|
100
lib/widgets/VideoWidget.dart
Normal file
100
lib/widgets/VideoWidget.dart
Normal file
@ -0,0 +1,100 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:f0ckapp/models/MediaItem.dart';
|
||||
import 'package:f0ckapp/widgets/VideoOverlay.dart';
|
||||
|
||||
class VideoWidget extends StatefulWidget {
|
||||
final MediaItem details;
|
||||
const VideoWidget({super.key, required this.details});
|
||||
|
||||
@override
|
||||
State createState() => _VideoWidgetState();
|
||||
}
|
||||
|
||||
class _VideoWidgetState extends State<VideoWidget> {
|
||||
late VideoPlayerController _controller;
|
||||
bool _showControls = false;
|
||||
Timer? _hideControlsTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initController();
|
||||
}
|
||||
|
||||
Future<void> _initController() async {
|
||||
_controller = VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.details.mediaUrl),
|
||||
);
|
||||
await _controller.initialize();
|
||||
setState(() {});
|
||||
|
||||
_controller.addListener(() => setState(() {}));
|
||||
_controller.play();
|
||||
_controller.setLooping(true);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
_hideControlsTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onTap({bool ctrlButton = false}) {
|
||||
if (!ctrlButton) {
|
||||
setState(() => _showControls = !_showControls);
|
||||
}
|
||||
|
||||
if (_showControls) {
|
||||
_hideControlsTimer?.cancel();
|
||||
_hideControlsTimer = Timer(Duration(seconds: 5), () {
|
||||
setState(() => _showControls = false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isAudio = widget.details.mime.startsWith('audio');
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: _controller.value.isInitialized
|
||||
? _controller.value.aspectRatio
|
||||
: 9 / 16,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: _onTap,
|
||||
child: isAudio
|
||||
? CachedNetworkImage(
|
||||
imageUrl: widget.details.coverUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) =>
|
||||
CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => Image.network(
|
||||
"https://f0ck.me/s/img/music.webp",
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
: _controller.value.isInitialized
|
||||
? VideoPlayer(_controller)
|
||||
: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
if (_controller.value.isInitialized && _showControls) ...[
|
||||
VideoControlsOverlay(controller: _controller, button: () => _onTap(ctrlButton: true)),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
import 'package:f0ckapp/models/mediaitem.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class VideoWidget extends StatefulWidget {
|
||||
final MediaItem details;
|
||||
const VideoWidget({super.key, required this.details});
|
||||
|
||||
@override
|
||||
State createState() => _VideoWidgetState();
|
||||
}
|
||||
|
||||
class _VideoWidgetState extends State<VideoWidget> {
|
||||
late VideoPlayerController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initController();
|
||||
}
|
||||
|
||||
Future<void> _initController() async {
|
||||
_controller = VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.details.mediaUrl),
|
||||
);
|
||||
await _controller.initialize();
|
||||
setState(() {});
|
||||
|
||||
_controller.addListener(() => setState(() {}));
|
||||
_controller.play();
|
||||
_controller.setLooping(true);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
String _formatDuration(Duration duration) {
|
||||
String twoDigits(int n) => n.toString().padLeft(2, '0');
|
||||
final minutes = twoDigits(duration.inMinutes.remainder(60));
|
||||
final seconds = twoDigits(duration.inSeconds.remainder(60));
|
||||
return "$minutes:$seconds";
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isAudio = widget.details.mime.startsWith('audio');
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: _controller.value.isInitialized
|
||||
? _controller.value.aspectRatio
|
||||
: 9 / 16,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_controller.value.isPlaying
|
||||
? _controller.pause()
|
||||
: _controller.play();
|
||||
});
|
||||
},
|
||||
child: isAudio
|
||||
? Image.network(widget.details.coverUrl, fit: BoxFit.cover)
|
||||
: _controller.value.isInitialized
|
||||
? VideoPlayer(_controller)
|
||||
: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
if (_controller.value.isInitialized)
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 10,
|
||||
child: VideoProgressIndicator(
|
||||
_controller,
|
||||
allowScrubbing: true,
|
||||
padding: EdgeInsets.only(bottom: 0),
|
||||
colors: VideoProgressColors(
|
||||
playedColor: Colors.red,
|
||||
bufferedColor: Colors.grey,
|
||||
backgroundColor: Colors.black.withAlpha(128),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left:
|
||||
(_controller.value.position.inMilliseconds /
|
||||
_controller.value.duration.inMilliseconds) *
|
||||
MediaQuery.of(context).size.width -
|
||||
6,
|
||||
bottom: -1,
|
||||
child: Container(
|
||||
width: 12,
|
||||
height: 12,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
border: Border.all(color: Colors.red, width: 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_controller.value.isInitialized)
|
||||
SizedBox(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_formatDuration(_controller.value.position),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.replay_10),
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
_controller.seekTo(
|
||||
_controller.value.position -
|
||||
const Duration(seconds: 10),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
color: Colors.white,
|
||||
icon: Icon(
|
||||
_controller.value.isPlaying
|
||||
? Icons.pause
|
||||
: Icons.play_arrow,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_controller.value.isPlaying
|
||||
? _controller.pause()
|
||||
: _controller.play();
|
||||
});
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
color: Colors.white,
|
||||
icon: const Icon(Icons.forward_10),
|
||||
onPressed: () {
|
||||
_controller.seekTo(
|
||||
_controller.value.position +
|
||||
const Duration(seconds: 10),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
_formatDuration(_controller.value.duration),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -5,8 +5,12 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_foundation
|
||||
import sqflite_darwin
|
||||
import video_player_avfoundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
}
|
||||
|
208
pubspec.lock
208
pubspec.lock
@ -17,6 +17,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cached_network_image
|
||||
sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
cached_network_image_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_platform_interface
|
||||
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.1"
|
||||
cached_network_image_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -41,6 +65,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -65,11 +97,43 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_cache_manager
|
||||
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -168,6 +232,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
octo_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: octo_image
|
||||
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -176,6 +248,62 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.17"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.6"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -184,6 +312,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rxdart
|
||||
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.28.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -197,6 +333,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
sprintf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sprintf
|
||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
sqflite:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
sqflite_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_android
|
||||
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.5"
|
||||
sqflite_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_darwin
|
||||
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
sqflite_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_platform_interface
|
||||
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -221,6 +405,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -245,6 +437,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -309,6 +509,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
sdks:
|
||||
dart: ">=3.9.0-100.2.beta <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.20+20
|
||||
version: 1.0.22+22
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.0-100.2.beta
|
||||
@ -36,6 +36,7 @@ dependencies:
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.8
|
||||
cached_network_image: ^3.4.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Reference in New Issue
Block a user