✨ Shuffle mode swiper
This commit is contained in:
parent
7dc198f0a7
commit
42c3e5ff0a
@ -2,10 +2,9 @@ import 'package:get/get.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:solian/models/pagination.dart';
|
import 'package:solian/models/pagination.dart';
|
||||||
import 'package:solian/models/post.dart';
|
import 'package:solian/models/post.dart';
|
||||||
|
import 'package:solian/providers/content/posts.dart';
|
||||||
|
|
||||||
import '../providers/content/posts.dart';
|
class PostListController extends GetxController {
|
||||||
|
|
||||||
class PostListController {
|
|
||||||
/// The polling source modifier.
|
/// The polling source modifier.
|
||||||
/// - `0`: default recommendations
|
/// - `0`: default recommendations
|
||||||
/// - `1`: shuffle mode
|
/// - `1`: shuffle mode
|
||||||
@ -46,14 +45,25 @@ class PostListController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RxBool isBusy = false.obs;
|
RxBool isBusy = false.obs;
|
||||||
|
RxBool isPreparing = false.obs;
|
||||||
|
|
||||||
|
RxInt focusCursor = 0.obs;
|
||||||
|
Post get focusPost => postList[focusCursor.value];
|
||||||
|
|
||||||
|
RxInt postTotal = 0.obs;
|
||||||
RxList<Post> postList = RxList.empty(growable: true);
|
RxList<Post> postList = RxList.empty(growable: true);
|
||||||
|
|
||||||
RxInt nextPageKey = 0.obs;
|
RxInt nextPageKey = 0.obs;
|
||||||
RxBool hasMore = true.obs;
|
RxBool hasMore = true.obs;
|
||||||
|
|
||||||
Future<void> reloadAllOver() async {
|
Future<void> reloadAllOver() async {
|
||||||
|
isPreparing.value = true;
|
||||||
|
|
||||||
|
focusCursor.value = 0;
|
||||||
nextPageKey.value = 0;
|
nextPageKey.value = 0;
|
||||||
|
postList.clear();
|
||||||
hasMore.value = true;
|
hasMore.value = true;
|
||||||
|
|
||||||
_resetPagingController();
|
_resetPagingController();
|
||||||
final result = await loadMore();
|
final result = await loadMore();
|
||||||
if (result != null && hasMore.value) {
|
if (result != null && hasMore.value) {
|
||||||
@ -62,19 +72,26 @@ class PostListController {
|
|||||||
pagingController.appendLastPage(result);
|
pagingController.appendLastPage(result);
|
||||||
}
|
}
|
||||||
_initPagingController();
|
_initPagingController();
|
||||||
|
|
||||||
|
isPreparing.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Post>?> loadMore() async {
|
Future<List<Post>?> loadMore() async {
|
||||||
final result = await _loadPosts(nextPageKey.value);
|
final result = await _loadPosts(nextPageKey.value);
|
||||||
|
|
||||||
if (result != null && result.length >= 10) {
|
if (result != null && result.length >= 10) {
|
||||||
nextPageKey.value = nextPageKey.value + result.length;
|
postList.addAll(result);
|
||||||
|
nextPageKey.value += result.length;
|
||||||
hasMore.value = true;
|
hasMore.value = true;
|
||||||
} else if (result != null) {
|
} else if (result != null) {
|
||||||
nextPageKey.value = nextPageKey.value + result.length;
|
postList.addAll(result);
|
||||||
|
nextPageKey.value += result.length;
|
||||||
hasMore.value = false;
|
hasMore.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final idx = <dynamic>{};
|
||||||
|
postList.retainWhere((x) => idx.add(x.id));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,12 +115,14 @@ class PostListController {
|
|||||||
final PaginationResult result = PaginationResult.fromJson(resp.body);
|
final PaginationResult result = PaginationResult.fromJson(resp.body);
|
||||||
final out = result.data?.map((e) => Post.fromJson(e)).toList();
|
final out = result.data?.map((e) => Post.fromJson(e)).toList();
|
||||||
|
|
||||||
if (out != null) postList.addAll(out.cast<Post>());
|
postTotal.value = result.count;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
pagingController.dispose();
|
pagingController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import 'package:solian/widgets/app_bar_title.dart';
|
|||||||
import 'package:solian/widgets/current_state_action.dart';
|
import 'package:solian/widgets/current_state_action.dart';
|
||||||
import 'package:solian/widgets/app_bar_leading.dart';
|
import 'package:solian/widgets/app_bar_leading.dart';
|
||||||
import 'package:solian/widgets/feed/feed_list.dart';
|
import 'package:solian/widgets/feed/feed_list.dart';
|
||||||
|
import 'package:solian/widgets/posts/post_shuffle_swiper.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
@ -19,19 +20,20 @@ class HomeScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomeScreenState extends State<HomeScreen>
|
class _HomeScreenState extends State<HomeScreen>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
final PostListController _postController = PostListController();
|
late final PostListController _postController;
|
||||||
|
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
Get.lazyPut(() => PostListController());
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_postController = Get.find();
|
||||||
_tabController = TabController(length: 2, vsync: this);
|
_tabController = TabController(length: 2, vsync: this);
|
||||||
_tabController.addListener(() {
|
_tabController.addListener(() {
|
||||||
switch (_tabController.index) {
|
switch (_tabController.index) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
if (_postController.mode.value == _tabController.index) break;
|
if (_postController.mode.value == _tabController.index) return;
|
||||||
_postController.mode.value = _tabController.index;
|
_postController.mode.value = _tabController.index;
|
||||||
_postController.reloadAllOver();
|
_postController.reloadAllOver();
|
||||||
}
|
}
|
||||||
@ -42,6 +44,8 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
child: SafeArea(
|
||||||
|
bottom: false,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
@ -55,7 +59,8 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
body: NestedScrollView(
|
body: NestedScrollView(
|
||||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
headerSliverBuilder:
|
||||||
|
(BuildContext context, bool innerBoxIsScrolled) {
|
||||||
return [
|
return [
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
title: AppBarTitle('home'.tr),
|
title: AppBarTitle('home'.tr),
|
||||||
@ -80,19 +85,28 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
body: TabBarView(
|
body: Obx(() {
|
||||||
|
if (_postController.isPreparing.isTrue) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TabBarView(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: [
|
children: [
|
||||||
RefreshIndicator(
|
RefreshIndicator(
|
||||||
onRefresh: () => _postController.reloadAllOver(),
|
onRefresh: () => _postController.reloadAllOver(),
|
||||||
child: CustomScrollView(slivers: [
|
child: CustomScrollView(slivers: [
|
||||||
FeedListWidget(controller: _postController.pagingController),
|
FeedListWidget(
|
||||||
|
controller: _postController.pagingController),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
CustomScrollView(slivers: [
|
PostShuffleSwiper(controller: _postController),
|
||||||
FeedListWidget(controller: _postController.pagingController),
|
|
||||||
]),
|
|
||||||
],
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -182,7 +182,10 @@ class _PostItemState extends State<PostItem> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final hasAttachment = item.body['attachments']?.isNotEmpty ?? false;
|
final List<int> attachments = item.body['attachments'] is List
|
||||||
|
? item.body['attachments']?.cast<int>()
|
||||||
|
: List.empty();
|
||||||
|
final hasAttachment = attachments.isNotEmpty;
|
||||||
|
|
||||||
if (widget.isCompact) {
|
if (widget.isCompact) {
|
||||||
return Column(
|
return Column(
|
||||||
@ -199,7 +202,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
bottom: hasAttachment ? 4 : 0,
|
bottom: hasAttachment ? 4 : 0,
|
||||||
),
|
),
|
||||||
buildFooter().paddingOnly(left: 16),
|
buildFooter().paddingOnly(left: 16),
|
||||||
if (item.body['attachments']?.isNotEmpty ?? false)
|
if (attachments.isNotEmpty)
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
@ -209,7 +212,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
).paddingOnly(right: 6),
|
).paddingOnly(right: 6),
|
||||||
Text(
|
Text(
|
||||||
'postAttachmentTip'.trParams(
|
'postAttachmentTip'.trParams(
|
||||||
{'count': item.body['attachments']!.length.toString()},
|
{'count': attachments.length.toString()},
|
||||||
),
|
),
|
||||||
style: TextStyle(color: _unFocusColor),
|
style: TextStyle(color: _unFocusColor),
|
||||||
)
|
)
|
||||||
@ -293,8 +296,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
),
|
),
|
||||||
child: AttachmentList(
|
child: AttachmentList(
|
||||||
parentId: widget.item.id.toString(),
|
parentId: widget.item.id.toString(),
|
||||||
attachmentsId:
|
attachmentsId: attachments,
|
||||||
item.body['attachments']?.cast<int>() ?? List.empty(),
|
|
||||||
divided: true,
|
divided: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
62
lib/widgets/posts/post_shuffle_swiper.dart
Normal file
62
lib/widgets/posts/post_shuffle_swiper.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_card_swiper/flutter_card_swiper.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:solian/controllers/post_list_controller.dart';
|
||||||
|
import 'package:solian/widgets/posts/post_single_display.dart';
|
||||||
|
|
||||||
|
class PostShuffleSwiper extends StatefulWidget {
|
||||||
|
final PostListController controller;
|
||||||
|
|
||||||
|
const PostShuffleSwiper({super.key, required this.controller});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PostShuffleSwiper> createState() => _PostShuffleSwiperState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PostShuffleSwiperState extends State<PostShuffleSwiper> {
|
||||||
|
final CardSwiperController _swiperController = CardSwiperController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Obx(
|
||||||
|
() => CardSwiper(
|
||||||
|
initialIndex: 0,
|
||||||
|
isLoop: false,
|
||||||
|
controller: _swiperController,
|
||||||
|
cardsCount: widget.controller.postTotal.value,
|
||||||
|
numberOfCardsDisplayed: 2,
|
||||||
|
allowedSwipeDirection: const AllowedSwipeDirection.symmetric(
|
||||||
|
horizontal: true,
|
||||||
|
),
|
||||||
|
cardBuilder: (context, index, percentThresholdX, percentThresholdY) {
|
||||||
|
if (widget.controller.postList.length <= index) {
|
||||||
|
return Card(
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
).paddingAll(24),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final element = widget.controller.postList[index];
|
||||||
|
return PostSingleDisplay(
|
||||||
|
key: Key('p${element.id}'),
|
||||||
|
item: element,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
onSwipe: (prevIndex, currIndex, dir) {
|
||||||
|
if (prevIndex + 2 >= widget.controller.postList.length) {
|
||||||
|
// Automatically load more
|
||||||
|
widget.controller.loadMore();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
).paddingOnly(bottom: MediaQuery.of(context).padding.bottom),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_swiperController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
24
lib/widgets/posts/post_single_display.dart
Normal file
24
lib/widgets/posts/post_single_display.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:solian/models/post.dart';
|
||||||
|
import 'package:solian/widgets/posts/post_item.dart';
|
||||||
|
|
||||||
|
class PostSingleDisplay extends StatelessWidget {
|
||||||
|
final Post item;
|
||||||
|
|
||||||
|
const PostSingleDisplay({super.key, required this.item});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Card(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: PostItem(
|
||||||
|
item: item,
|
||||||
|
).paddingSymmetric(horizontal: 10, vertical: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
52
pubspec.lock
52
pubspec.lock
@ -301,10 +301,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dev_build
|
name: dev_build
|
||||||
sha256: cd2d110dc7ca372cc45d4eba79e4be9eb54ceda673687305b82be367aad8c652
|
sha256: "5600100e28f7424ed53728e8e7aa6bc0e0506ec04bb49a82616f62112c1822c3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+7"
|
version: "1.0.0+8"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -389,10 +389,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file_selector_windows
|
name: file_selector_windows
|
||||||
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
|
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.3+1"
|
version: "0.9.3+2"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -506,10 +506,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_cache_manager
|
name: flutter_cache_manager
|
||||||
sha256: "395d6b7831f21f3b989ebedbb785545932adb9afe2622c1ffacf7f4b53a7e544"
|
sha256: ceff65d74d907b1b772e22cf04daad60fb472461638977d9fae8b00a63e01e3d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.2"
|
version: "3.3.3"
|
||||||
|
flutter_card_swiper:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_card_swiper
|
||||||
|
sha256: "880ad669017154d6d1f8c3abd861db08af97b3b7b0f7d7d5cbde690a9253811d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -620,10 +628,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_webrtc
|
name: flutter_webrtc
|
||||||
sha256: "3f115def06fb80df7c2e9f97b7d73c1b43a973211fc56df69638a663529f56c6"
|
sha256: d305793e6737c59a81c45b18484e1f985710827704eeb9092573387efcbae272
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.4"
|
version: "0.11.5"
|
||||||
font_awesome_flutter:
|
font_awesome_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -716,10 +724,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image_picker_android
|
name: image_picker_android
|
||||||
sha256: cea2bd5b9fcff039a4901d3b13c67fe747f940be9ba76bde1bcd218d168eeb7f
|
sha256: a26dc9a03fe042440c1e4be554fb0fceae2bf6d887d7467fc48c688fa4a81889
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.12+6"
|
version: "0.8.12+7"
|
||||||
image_picker_for_web:
|
image_picker_for_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -852,10 +860,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: livekit_client
|
name: livekit_client
|
||||||
sha256: "0c369b25e56910650184049cc713bb38a920cbe2e0d10db83fac400a3c393e2b"
|
sha256: e6b1e8a3cdcae95f7e62c0371590648444bac245fce3a1bcfb4ec05889ad82f3
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.2"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1188,10 +1196,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process_run
|
name: process_run
|
||||||
sha256: "6052115540ad88715d6bcee60656970f70c68c85846d1948b92e435f0382899e"
|
sha256: "6dc6f83198b876431c9823a1f93a4c147470e7f239403c37caca702cf35e146f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+1"
|
version: "1.0.0+3"
|
||||||
protobuf:
|
protobuf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1268,10 +1276,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: rxdart
|
name: rxdart
|
||||||
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
|
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.7"
|
version: "0.28.0"
|
||||||
safe_local_storage:
|
safe_local_storage:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1340,18 +1348,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sentry
|
name: sentry
|
||||||
sha256: cbc29cbdd8a047aab3df42f826daf07e58dfb2e1d550895d1021a6d4e618b00d
|
sha256: "60756499f09c3ed944640d7993ac527a89f7c3033f13ec12ae145706b269b5c8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.4.0"
|
version: "8.5.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sentry_flutter
|
name: sentry_flutter
|
||||||
sha256: "96ce085e1be6c9963d93d42d6ba5c67484c076c59d25c94a7ba906549dc6c635"
|
sha256: "26cfe89cb08a60d9bc0c4e748a0508e223ae378265aec8ed2a2b48f0d2c936b9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.4.0"
|
version: "8.5.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1633,10 +1641,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_windows
|
name: url_launcher_windows
|
||||||
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
|
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -54,6 +54,7 @@ dependencies:
|
|||||||
pasteboard: ^0.2.0
|
pasteboard: ^0.2.0
|
||||||
desktop_drop: ^0.4.4
|
desktop_drop: ^0.4.4
|
||||||
badges: ^3.1.2
|
badges: ^3.1.2
|
||||||
|
flutter_card_swiper: ^7.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user