👽 Update API to microservices

♻️ Refactor router pushes
This commit is contained in:
2025-07-17 14:35:09 +08:00
parent a7454edec0
commit e6c58b7b63
109 changed files with 9156 additions and 344 deletions

View File

@@ -29,7 +29,7 @@ part 'hub.g.dart';
Future<SnPublisherStats?> publisherStats(Ref ref, String? uname) async {
if (uname == null) return null;
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/publishers/$uname/stats');
final resp = await apiClient.get('/sphere/publishers/$uname/stats');
return SnPublisherStats.fromJson(resp.data);
}
@@ -37,7 +37,9 @@ Future<SnPublisherStats?> publisherStats(Ref ref, String? uname) async {
Future<SnPublisherMember?> publisherIdentity(Ref ref, String uname) async {
try {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get('/publishers/$uname/members/me');
final response = await apiClient.get(
'/sphere/publishers/$uname/members/me',
);
return SnPublisherMember.fromJson(response.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -51,14 +53,14 @@ Future<SnPublisherMember?> publisherIdentity(Ref ref, String uname) async {
Future<Map<String, bool>> publisherFeatures(Ref ref, String? uname) async {
if (uname == null) return {};
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get('/publishers/$uname/features');
final response = await apiClient.get('/sphere/publishers/$uname/features');
return Map<String, bool>.from(response.data);
}
@riverpod
Future<List<SnPublisherMember>> publisherInvites(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/publishers/invites');
final resp = await client.get('/sphere/publishers/invites');
return resp.data
.map((e) => SnPublisherMember.fromJson(e))
.cast<SnPublisherMember>()
@@ -141,7 +143,7 @@ class CreatorHubScreen extends HookConsumerWidget {
);
void updatePublisher() {
context.push('/creators/${currentPublisher.value!.name}/edit').then((
context.pushNamed('creatorEdit', pathParameters: {'name': currentPublisher.value!.name}).then((
value,
) async {
if (value == null) return;
@@ -156,7 +158,7 @@ class CreatorHubScreen extends HookConsumerWidget {
(confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/publishers/${currentPublisher.value!.name}');
client.delete('/sphere/publishers/${currentPublisher.value!.name}');
ref.invalidate(publishersManagedProvider);
currentPublisher.value = null;
}
@@ -324,7 +326,7 @@ class CreatorHubScreen extends HookConsumerWidget {
subtitle: Text('createPublisherHint').tr(),
trailing: const Icon(Symbols.chevron_right),
onTap: () {
context.push('/creators/new').then((value) {
context.pushNamed('creatorNew').then((value) {
if (value != null) {
ref.invalidate(publishersManagedProvider);
}
@@ -348,9 +350,7 @@ class CreatorHubScreen extends HookConsumerWidget {
horizontal: 24,
),
onTap: () {
context.push(
'/creators/${currentPublisher.value!.name}/stickers',
);
context.pushNamed('creatorStickers', pathParameters: {'name': currentPublisher.value!.name});
},
),
ListTile(
@@ -362,9 +362,7 @@ class CreatorHubScreen extends HookConsumerWidget {
horizontal: 24,
),
onTap: () {
context.push(
'/creators/${currentPublisher.value!.name}/posts',
);
context.pushNamed('creatorPosts', pathParameters: {'name': currentPublisher.value!.name});
},
),
ListTile(

View File

@@ -6,7 +6,7 @@ part of 'hub.dart';
// RiverpodGenerator
// **************************************************************************
String _$publisherStatsHash() => r'315705881d116b2aeac93f94f5ee2bc816d9f0f6';
String _$publisherStatsHash() => r'eea4ed98bf165cc785874f83b912bb7e23d1f7bc';
/// Copied from Dart SDK
class _SystemHash {
@@ -149,7 +149,7 @@ class _PublisherStatsProviderElement
String? get uname => (origin as PublisherStatsProvider).uname;
}
String _$publisherIdentityHash() => r'f7fd986a303a729ca5557022fceb37cd01fa17f3';
String _$publisherIdentityHash() => r'299372f25fa4b2bf8e11a8ba2d645100fc38e76f';
/// See also [publisherIdentity].
@ProviderFor(publisherIdentity)
@@ -271,7 +271,7 @@ class _PublisherIdentityProviderElement
String get uname => (origin as PublisherIdentityProvider).uname;
}
String _$publisherFeaturesHash() => r'34db65d9a4b6b0c6961733ae79e67f25d5d111d3';
String _$publisherFeaturesHash() => r'08bace2d9a3da227ecec0cbf8709e55ee0646ca2';
/// See also [publisherFeatures].
@ProviderFor(publisherFeatures)
@@ -393,7 +393,7 @@ class _PublisherFeaturesProviderElement
String? get uname => (origin as PublisherFeaturesProvider).uname;
}
String _$publisherInvitesHash() => r'488cd443407895ce11f4edff07cb6ea58f2aa018';
String _$publisherInvitesHash() => r'93aafc2f02af0a7a055ec1770b3999363dfaabdc';
/// See also [publisherInvites].
@ProviderFor(publisherInvites)

View File

@@ -30,8 +30,9 @@ class CreatorPostListScreen extends HookConsumerWidget {
subtitle: Text('Create a regular post'),
onTap: () async {
Navigator.pop(context);
final result = await context.push(
'/posts/compose?type=0',
final result = await context.pushNamed(
'postCompose',
queryParameters: {'type': '0'},
);
if (result == true) {
refreshKey.value++;
@@ -44,8 +45,9 @@ class CreatorPostListScreen extends HookConsumerWidget {
subtitle: Text('Create a detailed article'),
onTap: () async {
Navigator.pop(context);
final result = await context.push(
'/posts/compose?type=1',
final result = await context.pushNamed(
'postCompose',
queryParameters: {'type': '1'},
);
if (result == true) {
refreshKey.value++;

View File

@@ -29,7 +29,7 @@ part 'publishers.g.dart';
@riverpod
Future<List<SnPublisher>> publishersManaged(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/publishers');
final resp = await client.get('/sphere/publishers');
return resp.data
.map((e) => SnPublisher.fromJson(e))
.cast<SnPublisher>()
@@ -40,7 +40,7 @@ Future<List<SnPublisher>> publishersManaged(Ref ref) async {
Future<SnPublisher?> publisher(Ref ref, String? identifier) async {
if (identifier == null) return null;
final client = ref.watch(apiClientProvider);
final resp = await client.get('/publishers/$identifier');
final resp = await client.get('/sphere/publishers/$identifier');
return SnPublisher.fromJson(resp.data);
}

View File

@@ -6,7 +6,7 @@ part of 'publishers.dart';
// RiverpodGenerator
// **************************************************************************
String _$publishersManagedHash() => r'1ea611c8d45c46002976c99bf4ee7f60bd6dbf8e';
String _$publishersManagedHash() => r'ea83759fed9bd5119738b4d09f12b4476959e0a3';
/// See also [publishersManaged].
@ProviderFor(publishersManaged)
@@ -25,7 +25,7 @@ final publishersManagedProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef PublishersManagedRef = AutoDisposeFutureProviderRef<List<SnPublisher>>;
String _$publisherHash() => r'd66f2efba7ae449b9b460a4da34ce48cf3b16fe5';
String _$publisherHash() => r'18fb5c6b3d79dd8af4fbee108dec1a0e8a034038';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -74,7 +74,7 @@ class StickerPackDetailScreen extends HookConsumerWidget {
IconButton(
icon: const Icon(Symbols.add_circle),
onPressed: () {
context.push('/creators/stickers/$id/new').then((
context.pushNamed('creatorStickerNew', pathParameters: {'packId': id}).then((
value,
) {
if (value != null) {
@@ -173,9 +173,9 @@ class StickerPackDetailScreen extends HookConsumerWidget {
title: 'edit'.tr(),
image: MenuImage.icon(Symbols.edit),
callback: () {
context
.push(
'/creators/stickers/$id/edit/${sticker.id}',
context.pushNamed(
'creatorStickerEdit',
pathParameters: {'packId': id, 'id': sticker.id},
)
.then((value) {
if (value != null) {

View File

@@ -1,6 +1,5 @@
// dart format width=80
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
@@ -74,6 +73,130 @@ as String,
}
/// Adds pattern-matching-related methods to [StickerWithPackQuery].
extension StickerWithPackQueryPatterns on StickerWithPackQuery {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _StickerWithPackQuery value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _StickerWithPackQuery() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _StickerWithPackQuery value) $default,){
final _that = this;
switch (_that) {
case _StickerWithPackQuery():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _StickerWithPackQuery value)? $default,){
final _that = this;
switch (_that) {
case _StickerWithPackQuery() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String packId, String id)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _StickerWithPackQuery() when $default != null:
return $default(_that.packId,_that.id);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String packId, String id) $default,) {final _that = this;
switch (_that) {
case _StickerWithPackQuery():
return $default(_that.packId,_that.id);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String packId, String id)? $default,) {final _that = this;
switch (_that) {
case _StickerWithPackQuery() when $default != null:
return $default(_that.packId,_that.id);case _:
return null;
}
}
}
/// @nodoc

View File

@@ -28,7 +28,7 @@ class StickersScreen extends HookConsumerWidget {
actions: [
IconButton(
onPressed: () {
context.push('/creators/stickers/new?pubName=$pubName').then((
context.pushNamed('creatorStickerPackNew', queryParameters: {'pubName': pubName}).then((
value,
) {
if (value != null) {
@@ -71,7 +71,7 @@ class SliverStickerPacksList extends HookConsumerWidget {
subtitle: Text(sticker.description),
trailing: const Icon(Symbols.chevron_right),
onTap: () {
context.push('/creators/$pubName/stickers/${sticker.id}');
context.pushNamed('creatorStickerPackDetail', pathParameters: {'pubName': pubName, 'packId': sticker.id});
},
);
},

View File

@@ -20,7 +20,7 @@ class WebFeedListScreen extends ConsumerWidget {
floatingActionButton: FloatingActionButton(
child: const Icon(Symbols.add),
onPressed: () {
context.push('/creators/$pubName/feeds/new');
context.pushNamed('creatorFeedNew', pathParameters: {'name': pubName});
},
),
body: feedsAsync.when(
@@ -62,7 +62,7 @@ class WebFeedListScreen extends ConsumerWidget {
),
trailing: const Icon(Symbols.chevron_right),
onTap: () {
context.push('/creators/$pubName/feeds/${feed.id}');
context.pushNamed('creatorFeedEdit', pathParameters: {'name': pubName, 'feedId': feed.id});
},
),
);