✨ Subscriptions
This commit is contained in:
parent
06aa1fb359
commit
d87e67bd17
@ -410,5 +410,8 @@
|
|||||||
"userLevel13": "Immortal",
|
"userLevel13": "Immortal",
|
||||||
"postBrowsingIn": "Browsing in @region",
|
"postBrowsingIn": "Browsing in @region",
|
||||||
"needRestartToApply": "Restart the application to take effect",
|
"needRestartToApply": "Restart the application to take effect",
|
||||||
"holdToSeeDetail": "Long press / Mouse hover to see detail"
|
"holdToSeeDetail": "Long press / Mouse hover to see detail",
|
||||||
|
"subscribe": "Subscribe",
|
||||||
|
"subscribed": "Subscribed",
|
||||||
|
"unsubscribe": "Unsubscribe"
|
||||||
}
|
}
|
||||||
|
@ -411,5 +411,8 @@
|
|||||||
"userLevel13": "万古流芳",
|
"userLevel13": "万古流芳",
|
||||||
"postBrowsingIn": "浏览 @region 内的帖子中",
|
"postBrowsingIn": "浏览 @region 内的帖子中",
|
||||||
"needRestartToApply": "需要重启应用来生效",
|
"needRestartToApply": "需要重启应用来生效",
|
||||||
"holdToSeeDetail": "长按 / 鼠标悬浮来查看详情"
|
"holdToSeeDetail": "长按 / 鼠标悬浮来查看详情",
|
||||||
|
"subscribe": "订阅",
|
||||||
|
"subscribed": "已订阅",
|
||||||
|
"unsubscribe": "取消订阅"
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import 'package:solian/providers/last_read.dart';
|
|||||||
import 'package:solian/providers/link_expander.dart';
|
import 'package:solian/providers/link_expander.dart';
|
||||||
import 'package:solian/providers/navigation.dart';
|
import 'package:solian/providers/navigation.dart';
|
||||||
import 'package:solian/providers/stickers.dart';
|
import 'package:solian/providers/stickers.dart';
|
||||||
|
import 'package:solian/providers/subscription.dart';
|
||||||
import 'package:solian/providers/theme_switcher.dart';
|
import 'package:solian/providers/theme_switcher.dart';
|
||||||
import 'package:solian/providers/websocket.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
@ -151,6 +152,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
Get.lazyPut(() => LinkExpandProvider());
|
Get.lazyPut(() => LinkExpandProvider());
|
||||||
Get.lazyPut(() => DailySignProvider());
|
Get.lazyPut(() => DailySignProvider());
|
||||||
Get.lazyPut(() => LastReadProvider());
|
Get.lazyPut(() => LastReadProvider());
|
||||||
|
Get.lazyPut(() => SubscriptionProvider());
|
||||||
|
|
||||||
Get.find<WebSocketProvider>().requestPermissions();
|
Get.find<WebSocketProvider>().requestPermissions();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'account.g.dart';
|
part 'account.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'account_status.g.dart';
|
part 'account_status.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
|
|
||||||
part 'attachment.g.dart';
|
part 'attachment.g.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
|
|
||||||
part 'auth.g.dart';
|
part 'auth.g.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:livekit_client/livekit_client.dart';
|
import 'package:livekit_client/livekit_client.dart';
|
||||||
import 'package:solian/models/channel.dart';
|
import 'package:solian/models/channel.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
import 'package:solian/models/realm.dart';
|
import 'package:solian/models/realm.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/channel.dart';
|
import 'package:solian/models/channel.dart';
|
||||||
|
|
||||||
part 'event.g.dart';
|
part 'event.g.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'link.g.dart';
|
part 'link.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'notification.g.dart';
|
part 'notification.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'packet.g.dart';
|
part 'packet.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'pagination.g.dart';
|
part 'pagination.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
import 'package:solian/models/post_categories.dart';
|
import 'package:solian/models/post_categories.dart';
|
||||||
import 'package:solian/models/realm.dart';
|
import 'package:solian/models/realm.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
part 'post_categories.g.dart';
|
part 'post_categories.g.dart';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
|
|
||||||
part 'realm.g.dart';
|
part 'realm.g.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
|
|
||||||
part 'relations.g.dart';
|
part 'relations.g.dart';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
import 'package:solian/models/attachment.dart';
|
import 'package:solian/models/attachment.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
|
41
lib/models/subscription.dart
Normal file
41
lib/models/subscription.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:solian/models/account.dart';
|
||||||
|
import 'package:solian/models/post_categories.dart';
|
||||||
|
|
||||||
|
part 'subscription.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Subscription {
|
||||||
|
int id;
|
||||||
|
DateTime createdAt;
|
||||||
|
DateTime updatedAt;
|
||||||
|
DateTime? deletedAt;
|
||||||
|
int followerId;
|
||||||
|
Account follower;
|
||||||
|
int? accountId;
|
||||||
|
Account? account;
|
||||||
|
int? tagId;
|
||||||
|
Tag? tag;
|
||||||
|
int? categoryId;
|
||||||
|
Category? category;
|
||||||
|
|
||||||
|
Subscription({
|
||||||
|
required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.deletedAt,
|
||||||
|
required this.followerId,
|
||||||
|
required this.follower,
|
||||||
|
required this.accountId,
|
||||||
|
required this.account,
|
||||||
|
required this.tagId,
|
||||||
|
required this.tag,
|
||||||
|
required this.categoryId,
|
||||||
|
required this.category,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Subscription.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SubscriptionFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$SubscriptionToJson(this);
|
||||||
|
}
|
46
lib/models/subscription.g.dart
Normal file
46
lib/models/subscription.g.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'subscription.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Subscription _$SubscriptionFromJson(Map<String, dynamic> json) => Subscription(
|
||||||
|
id: (json['id'] as num).toInt(),
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt: json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
followerId: (json['follower_id'] as num).toInt(),
|
||||||
|
follower: Account.fromJson(json['follower'] as Map<String, dynamic>),
|
||||||
|
accountId: (json['account_id'] as num?)?.toInt(),
|
||||||
|
account: json['account'] == null
|
||||||
|
? null
|
||||||
|
: Account.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
|
tagId: (json['tag_id'] as num?)?.toInt(),
|
||||||
|
tag: json['tag'] == null
|
||||||
|
? null
|
||||||
|
: Tag.fromJson(json['tag'] as Map<String, dynamic>),
|
||||||
|
categoryId: (json['category_id'] as num?)?.toInt(),
|
||||||
|
category: json['category'] == null
|
||||||
|
? null
|
||||||
|
: Category.fromJson(json['category'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SubscriptionToJson(Subscription instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'follower_id': instance.followerId,
|
||||||
|
'follower': instance.follower.toJson(),
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
|
'tag_id': instance.tagId,
|
||||||
|
'tag': instance.tag?.toJson(),
|
||||||
|
'category_id': instance.categoryId,
|
||||||
|
'category': instance.category?.toJson(),
|
||||||
|
};
|
@ -97,8 +97,8 @@ class PostProvider extends GetConnect {
|
|||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Post>> listPostFeaturedReply(String alias) async {
|
Future<List<Post>> listPostFeaturedReply(String alias, {int take = 1}) async {
|
||||||
final resp = await get('/posts/$alias/replies/featured');
|
final resp = await get('/posts/$alias/replies/featured?take=$take');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw RequestException(resp);
|
throw RequestException(resp);
|
||||||
}
|
}
|
||||||
|
46
lib/providers/subscription.dart
Normal file
46
lib/providers/subscription.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:solian/exceptions/request.dart';
|
||||||
|
import 'package:solian/exceptions/unauthorized.dart';
|
||||||
|
import 'package:solian/models/subscription.dart';
|
||||||
|
import 'package:solian/providers/auth.dart';
|
||||||
|
|
||||||
|
class SubscriptionProvider extends GetxController {
|
||||||
|
Future<Subscription?> getSubscriptionOnUser(int userId) async {
|
||||||
|
final auth = Get.find<AuthProvider>();
|
||||||
|
if (!auth.isAuthorized.value) throw const UnauthorizedException();
|
||||||
|
|
||||||
|
final client = await auth.configureClient('co');
|
||||||
|
final resp = await client.get('/subscriptions/users/$userId');
|
||||||
|
if (resp.statusCode == 404) {
|
||||||
|
return null;
|
||||||
|
} else if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Subscription.fromJson(resp.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Subscription> subscribeToUser(int userId) async {
|
||||||
|
final auth = Get.find<AuthProvider>();
|
||||||
|
if (!auth.isAuthorized.value) throw const UnauthorizedException();
|
||||||
|
|
||||||
|
final client = await auth.configureClient('co');
|
||||||
|
final resp = await client.post('/subscriptions/users/$userId', {});
|
||||||
|
if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Subscription.fromJson(resp.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> unsubscribeFromUser(int userId) async {
|
||||||
|
final auth = Get.find<AuthProvider>();
|
||||||
|
if (!auth.isAuthorized.value) throw const UnauthorizedException();
|
||||||
|
|
||||||
|
final client = await auth.configureClient('co');
|
||||||
|
final resp = await client.delete('/subscriptions/users/$userId');
|
||||||
|
if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,10 @@ import 'package:solian/models/account.dart';
|
|||||||
import 'package:solian/models/attachment.dart';
|
import 'package:solian/models/attachment.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/models/subscription.dart';
|
||||||
import 'package:solian/providers/account_status.dart';
|
import 'package:solian/providers/account_status.dart';
|
||||||
import 'package:solian/providers/relation.dart';
|
import 'package:solian/providers/relation.dart';
|
||||||
|
import 'package:solian/providers/subscription.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
import 'package:solian/theme.dart';
|
import 'package:solian/theme.dart';
|
||||||
import 'package:solian/widgets/account/account_avatar.dart';
|
import 'package:solian/widgets/account/account_avatar.dart';
|
||||||
@ -37,12 +39,21 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
|
|
||||||
bool _isBusy = true;
|
bool _isBusy = true;
|
||||||
bool _isMakingFriend = false;
|
bool _isMakingFriend = false;
|
||||||
|
bool _isSubscribing = false;
|
||||||
bool _showMature = false;
|
bool _showMature = false;
|
||||||
|
|
||||||
Account? _userinfo;
|
Account? _userinfo;
|
||||||
|
Subscription? _subscription;
|
||||||
List<Post> _pinnedPosts = List.empty();
|
List<Post> _pinnedPosts = List.empty();
|
||||||
int _totalUpvote = 0, _totalDownvote = 0;
|
int _totalUpvote = 0, _totalDownvote = 0;
|
||||||
|
|
||||||
|
Future<void> _getSubscription() async {
|
||||||
|
setState(() => _isSubscribing = true);
|
||||||
|
_subscription = await Get.find<SubscriptionProvider>()
|
||||||
|
.getSubscriptionOnUser(_userinfo!.id);
|
||||||
|
setState(() => _isSubscribing = false);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _getUserinfo() async {
|
Future<void> _getUserinfo() async {
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
@ -70,7 +81,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getPinnedPosts() async {
|
Future<void> _getPinnedPosts() async {
|
||||||
final client = await ServiceFinder.configureClient('interactive');
|
final client = await ServiceFinder.configureClient('interactive');
|
||||||
final resp = await client.get('/users/${widget.name}/pin');
|
final resp = await client.get('/users/${widget.name}/pin');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
@ -115,8 +126,10 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_getUserinfo();
|
_getUserinfo().then((_) {
|
||||||
getPinnedPosts();
|
_getSubscription();
|
||||||
|
_getPinnedPosts();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildStatisticsEntry(String label, String content) {
|
Widget _buildStatisticsEntry(String label, String content) {
|
||||||
@ -180,6 +193,40 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (_userinfo != null && _subscription == null)
|
||||||
|
OutlinedButton(
|
||||||
|
style: const ButtonStyle(
|
||||||
|
visualDensity:
|
||||||
|
VisualDensity(horizontal: -4, vertical: -2),
|
||||||
|
),
|
||||||
|
onPressed: _isSubscribing
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
setState(() => _isSubscribing = true);
|
||||||
|
_subscription =
|
||||||
|
await Get.find<SubscriptionProvider>()
|
||||||
|
.subscribeToUser(_userinfo!.id);
|
||||||
|
setState(() => _isSubscribing = false);
|
||||||
|
},
|
||||||
|
child: Text('subscribe'.tr),
|
||||||
|
)
|
||||||
|
else if (_userinfo != null)
|
||||||
|
OutlinedButton(
|
||||||
|
style: const ButtonStyle(
|
||||||
|
visualDensity:
|
||||||
|
VisualDensity(horizontal: -4, vertical: -2),
|
||||||
|
),
|
||||||
|
onPressed: _isSubscribing
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
setState(() => _isSubscribing = true);
|
||||||
|
await Get.find<SubscriptionProvider>()
|
||||||
|
.unsubscribeFromUser(_userinfo!.id);
|
||||||
|
_subscription = null;
|
||||||
|
setState(() => _isSubscribing = false);
|
||||||
|
},
|
||||||
|
child: Text('unsubscribe'.tr),
|
||||||
|
),
|
||||||
if (_userinfo != null &&
|
if (_userinfo != null &&
|
||||||
!_relationshipProvider.hasFriend(_userinfo!))
|
!_relationshipProvider.hasFriend(_userinfo!))
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -245,7 +292,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
RefreshIndicator(
|
RefreshIndicator(
|
||||||
onRefresh: () => Future.wait([
|
onRefresh: () => Future.wait([
|
||||||
_postController.reloadAllOver(),
|
_postController.reloadAllOver(),
|
||||||
getPinnedPosts(),
|
_getPinnedPosts(),
|
||||||
]),
|
]),
|
||||||
child: CustomScrollView(slivers: [
|
child: CustomScrollView(slivers: [
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
|
@ -282,6 +282,8 @@ class _AttachmentItemVideoState extends State<_AttachmentItemVideo> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.item.alt,
|
widget.item.alt,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
@ -447,6 +449,8 @@ class _AttachmentItemAudioState extends State<_AttachmentItemAudio> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.item.alt,
|
widget.item.alt,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
@ -909,14 +909,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.7.0"
|
version: "10.7.0"
|
||||||
freezed_annotation:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: freezed_annotation
|
|
||||||
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.4"
|
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -68,7 +68,6 @@ dependencies:
|
|||||||
flutter_svg: ^2.0.10+1
|
flutter_svg: ^2.0.10+1
|
||||||
cross_file: ^0.3.4+2
|
cross_file: ^0.3.4+2
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
freezed_annotation: ^2.4.4
|
|
||||||
json_annotation: ^4.9.0
|
json_annotation: ^4.9.0
|
||||||
gap: ^3.0.1
|
gap: ^3.0.1
|
||||||
fl_chart: ^0.69.0
|
fl_chart: ^0.69.0
|
||||||
|
Loading…
Reference in New Issue
Block a user