👽 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

@@ -98,7 +98,10 @@ class AccountScreen extends HookConsumerWidget {
radius: 24,
),
onTap: () {
context.push('/account/${user.value!.name}');
context.pushNamed(
'accountProfile',
pathParameters: {'name': user.value!.name},
);
},
),
Expanded(
@@ -143,7 +146,7 @@ class AccountScreen extends HookConsumerWidget {
progress: user.value!.profile.levelingProgress,
),
onTap: () {
context.push('/account/me/leveling');
context.pushNamed('leveling');
},
).padding(horizontal: 12),
Row(
@@ -161,7 +164,7 @@ class AccountScreen extends HookConsumerWidget {
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.push('/creators');
context.pushNamed('creatorHub');
},
),
).height(140),
@@ -179,7 +182,7 @@ class AccountScreen extends HookConsumerWidget {
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.push('/developers');
context.pushNamed('developerHub');
},
),
).height(140),
@@ -202,7 +205,7 @@ class AccountScreen extends HookConsumerWidget {
],
),
onTap: () {
context.push('/account/notifications');
context.pushNamed('notifications');
},
),
ListTile(
@@ -212,7 +215,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('wallet').tr(),
onTap: () {
context.push('/account/wallet');
context.pushNamed('wallet');
},
),
ListTile(
@@ -222,7 +225,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('relationships').tr(),
onTap: () {
context.push('/account/relationships');
context.pushNamed('relationships');
},
),
ListTile(
@@ -231,7 +234,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: const EdgeInsets.only(left: 24, right: 17),
leading: const Icon(Symbols.gavel),
trailing: const Icon(Symbols.chevron_right),
onTap: () => context.push('/safety/reports/me'),
onTap: () => context.pushNamed('reportList'),
),
const Divider(height: 1).padding(vertical: 8),
ListTile(
@@ -241,7 +244,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('appSettings').tr(),
onTap: () {
context.push('/settings');
context.pushNamed('settings');
},
),
ListTile(
@@ -251,7 +254,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('updateYourProfile').tr(),
onTap: () {
context.push('/account/me/update');
context.pushNamed('profileUpdate');
},
),
ListTile(
@@ -261,7 +264,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('accountSettings').tr(),
onTap: () {
context.push('/account/me/settings');
context.pushNamed('accountSettings');
},
),
if (kDebugMode) const Divider(height: 1).padding(vertical: 8),
@@ -296,7 +299,7 @@ class AccountScreen extends HookConsumerWidget {
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('about').tr(),
onTap: () {
context.push('/about');
context.pushNamed('about');
},
),
ListTile(
@@ -336,7 +339,7 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
child: Card(
child: InkWell(
onTap: () {
context.push('/auth/create-account');
context.pushNamed('createAccount');
},
child: Padding(
padding: const EdgeInsets.all(16),
@@ -358,7 +361,7 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
child: Card(
child: InkWell(
onTap: () {
context.push('/auth/login');
context.pushNamed('login');
},
child: Padding(
padding: const EdgeInsets.all(16),
@@ -380,13 +383,13 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
children: [
TextButton(
onPressed: () {
context.push('/about');
context.pushNamed('about');
},
child: Text('about').tr(),
),
TextButton(
onPressed: () {
context.push('/settings');
context.pushNamed('settings');
},
child: Text('appSettings').tr(),
),

View File

@@ -28,14 +28,14 @@ part 'settings.g.dart';
@riverpod
Future<List<SnAuthFactor>> authFactors(Ref ref) async {
final client = ref.read(apiClientProvider);
final res = await client.get('/accounts/me/factors');
final res = await client.get('/id/accounts/me/factors');
return res.data.map<SnAuthFactor>((e) => SnAuthFactor.fromJson(e)).toList();
}
@riverpod
Future<List<SnContactMethod>> contactMethods(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/accounts/me/contacts');
final resp = await client.get('/id/accounts/me/contacts');
return resp.data
.map<SnContactMethod>((e) => SnContactMethod.fromJson(e))
.toList();
@@ -44,7 +44,7 @@ Future<List<SnContactMethod>> contactMethods(Ref ref) async {
@riverpod
Future<List<SnAccountConnection>> accountConnections(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/accounts/me/connections');
final resp = await client.get('/id/accounts/me/connections');
return resp.data
.map<SnAccountConnection>((e) => SnAccountConnection.fromJson(e))
.toList();
@@ -68,7 +68,7 @@ class AccountSettingsScreen extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/accounts/me');
await client.delete('/id/accounts/me');
if (context.mounted) {
showSnackBar('accountDeletionSent'.tr());
}

View File

@@ -6,7 +6,7 @@ part of 'settings.dart';
// RiverpodGenerator
// **************************************************************************
String _$authFactorsHash() => r'4bb65bc0c065c4091c209ee81e57ddef41051ae2';
String _$authFactorsHash() => r'24fe2f7b375b019d87fc3b85cbedbe857f399c0f';
/// See also [authFactors].
@ProviderFor(authFactors)
@@ -25,7 +25,7 @@ final authFactorsProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef AuthFactorsRef = AutoDisposeFutureProviderRef<List<SnAuthFactor>>;
String _$contactMethodsHash() => r'4d7952fc196dce4dc646314565a49c115fd1d292';
String _$contactMethodsHash() => r'76a1a93f61c51c44b32b4821f5112d58406155f0';
/// See also [contactMethods].
@ProviderFor(contactMethods)
@@ -45,7 +45,7 @@ final contactMethodsProvider =
// ignore: unused_element
typedef ContactMethodsRef = AutoDisposeFutureProviderRef<List<SnContactMethod>>;
String _$accountConnectionsHash() =>
r'38a309d596e0ea2539cd92ea86984e1e4fb346e4';
r'9f69e7f23e3e53c528d38b93d76f0c9efc9a83db';
/// See also [accountConnections].
@ProviderFor(accountConnections)

View File

@@ -31,7 +31,7 @@ class AuthFactorSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/accounts/me/factors/${factor.id}');
await client.delete('/id/accounts/me/factors/${factor.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -49,7 +49,7 @@ class AuthFactorSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/accounts/me/factors/${factor.id}/disable');
await client.post('/id/accounts/me/factors/${factor.id}/disable');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);

View File

@@ -74,7 +74,7 @@ class AccountConnectionSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/accounts/me/connections/${connection.id}');
await client.delete('/id/accounts/me/connections/${connection.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);

View File

@@ -25,7 +25,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/accounts/me/contacts/${contact.id}');
await client.delete('/id/accounts/me/contacts/${contact.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -38,7 +38,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/accounts/me/contacts/${contact.id}/verify');
await client.post('/id/accounts/me/contacts/${contact.id}/verify');
if (context.mounted) {
showSnackBar('contactMethodVerificationSent'.tr());
}
@@ -53,7 +53,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/accounts/me/contacts/${contact.id}/primary');
await client.post('/id/accounts/me/contacts/${contact.id}/primary');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);

View File

@@ -135,7 +135,7 @@ class AccountProfileScreen extends HookConsumerWidget {
showLoadingModal(context);
try {
final client = ref.watch(apiClientProvider);
await client.post('/relationships/${account.value!.id}/friends');
await client.post('/id/relationships/${account.value!.id}/friends');
ref.invalidate(accountRelationshipProvider(name));
} catch (err) {
showErrorAlert(err);
@@ -149,9 +149,9 @@ class AccountProfileScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
if (accountRelationship.value == null) {
await client.post('/relationships/${account.value!.id}/block');
await client.post('/id/relationships/${account.value!.id}/block');
} else {
await client.delete('/relationships/${account.value!.id}/block');
await client.delete('/id/relationships/${account.value!.id}/block');
}
ref.invalidate(accountRelationshipProvider(name));
} catch (err) {
@@ -164,7 +164,10 @@ class AccountProfileScreen extends HookConsumerWidget {
Future<void> directMessageAction() async {
if (!account.hasValue) return;
if (accountChat.value != null) {
context.push('/chat/${accountChat.value!.id}');
context.pushNamed(
'chatRoom',
pathParameters: {'id': accountChat.value!.id},
);
return;
}
showLoadingModal(context);
@@ -175,7 +178,9 @@ class AccountProfileScreen extends HookConsumerWidget {
data: {'related_user_id': account.value!.id},
);
final chat = SnChatRoom.fromJson(resp.data);
if (context.mounted) context.push('/chat/${chat.id}');
if (context.mounted) {
context.pushNamed('chatRoom', pathParameters: {'id': chat.id});
}
ref.invalidate(accountDirectChatProvider(name));
} catch (err) {
showErrorAlert(err);

View File

@@ -20,7 +20,7 @@ part 'relationship.g.dart';
@riverpod
Future<List<SnRelationship>> sentFriendRequest(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/relationships/requests');
final resp = await client.get('/id/relationships/requests');
return resp.data
.map((e) => SnRelationship.fromJson(e))
.cast<SnRelationship>()
@@ -221,7 +221,7 @@ class RelationshipScreen extends HookConsumerWidget {
if (result == null) return;
final client = ref.read(apiClientProvider);
await client.post('/relationships/${result.id}/friends');
await client.post('/id/relationships/${result.id}/friends');
ref.invalidate(sentFriendRequestProvider);
}
@@ -345,7 +345,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
Future<void> cancelRequest(SnRelationship request) async {
try {
final client = ref.read(apiClientProvider);
await client.delete('/relationships/${request.relatedId}/friends');
await client.delete('/id/relationships/${request.relatedId}/friends');
ref.invalidate(sentFriendRequestProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'relationship.dart';
// RiverpodGenerator
// **************************************************************************
String _$sentFriendRequestHash() => r'2efa72835b1740e0fe96bd347bce0f98b6ae80d6';
String _$sentFriendRequestHash() => r'dc02ace6cb755a01ab862c9fcff3b26de7f946cb';
/// See also [sentFriendRequest].
@ProviderFor(sentFriendRequest)

View File

@@ -0,0 +1,17 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/network.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'captcha.config.g.dart';
@riverpod
Future<String> captchaUrl(Ref ref) async {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/.well-known/services');
final serviceMapping = await resp.data;
var baseUrl = serviceMapping['DysonNetwork.Pass'] as String;
// The backend using self-signed certicates on development
// Which mobile simulator might not accept, use this to avoid errors
if (baseUrl.contains('https://localhost')) baseUrl = 'http://localhost:5216';
return '$baseUrl/captcha';
}

View File

@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'captcha.config.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$captchaUrlHash() => r'627caa2f2eb020a28a4b138122fe8e99915185f9';
/// See also [captchaUrl].
@ProviderFor(captchaUrl)
final captchaUrlProvider = AutoDisposeFutureProvider<String>.internal(
captchaUrl,
name: r'captchaUrlProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$captchaUrlHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef CaptchaUrlRef = AutoDisposeFutureProviderRef<String>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:island/pods/config.dart';
import 'package:island/screens/auth/captcha.config.dart';
import 'package:island/widgets/app_scaffold.dart';
class CaptchaScreen extends ConsumerWidget {
@@ -9,13 +9,15 @@ class CaptchaScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final serverUrl = ref.watch(serverUrlProvider);
final captchaUrl = ref.watch(captchaUrlProvider);
if (!captchaUrl.hasValue) return Center(child: CircularProgressIndicator());
return AppScaffold(
appBar: AppBar(title: Text("Anti-Robot")),
body: InAppWebView(
initialUrlRequest: URLRequest(
url: WebUri('$serverUrl/auth/captcha?redirect_uri=solink://captcha'),
url: WebUri('${captchaUrl.value}?redirect_uri=solian://captcha'),
),
shouldOverrideUrlLoading: (controller, navigationAction) async {
Uri? url = navigationAction.request.url;

View File

@@ -3,6 +3,7 @@
import 'dart:ui_web' as ui;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/config.dart';
import 'package:island/screens/auth/captcha.config.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:web/web.dart' as web;
import 'package:flutter/material.dart';
@@ -17,7 +18,7 @@ class CaptchaScreen extends ConsumerStatefulWidget {
class _CaptchaScreenState extends ConsumerState<CaptchaScreen> {
bool _isInitialized = false;
void _setupWebListener(String serverUrl) {
void _setupWebListener(String serverUrl) async {
web.window.onMessage.listen((event) {
if (event.data != null && event.data is String) {
final message = event.data as String;
@@ -29,9 +30,11 @@ class _CaptchaScreenState extends ConsumerState<CaptchaScreen> {
}
});
final captchaUrl = await ref.watch(captchaUrlProvider.future);
final iframe =
web.HTMLIFrameElement()
..src = '$serverUrl/auth/captcha'
..src = captchaUrl
..style.border = 'none'
..width = '100%'
..height = '100%';

View File

@@ -49,7 +49,7 @@ class CreateAccountScreen extends HookConsumerWidget {
showLoadingModal(context);
final client = ref.watch(apiClientProvider);
await client.post(
'/accounts',
'/id/accounts',
data: {
'name': usernameController.text,
'nick': nicknameController.text,
@@ -305,7 +305,7 @@ class _PostCreateModal extends HookConsumerWidget {
TextButton(
onPressed: () {
Navigator.pop(context);
context.pushReplacement('/auth/login');
context.pushReplacementNamed('login');
},
child: Text('login'.tr()),
),

View File

@@ -178,7 +178,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
// Get token if challenge is completed
final client = ref.watch(apiClientProvider);
final tokenResp = await client.post(
'/auth/token',
'/id/auth/token',
data: {
'grant_type': 'authorization_code',
'code': code ?? challenge!.id,
@@ -215,7 +215,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
if (name != null) {
final client = ref.watch(apiClientProvider);
await client.patch(
'/accounts/me/sessions/current/label',
'/id/accounts/me/sessions/current/label',
data: jsonEncode(name),
);
}
@@ -225,6 +225,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
useEffect(() {
if (challenge != null && challenge?.stepRemain == 0) {
Future(() {
if (isBusy.value) return;
isBusy.value = true;
getToken().catchError((err) {
showErrorAlert(err);
@@ -265,7 +266,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
// Pass challenge
final client = ref.watch(apiClientProvider);
final resp = await client.patch(
'/auth/challenge/${challenge!.id}',
'/id/auth/challenge/${challenge!.id}',
data: {'factor_id': factor!.id, 'password': pwd},
);
final result = SnAuthChallenge.fromJson(resp.data);
@@ -412,7 +413,7 @@ class _LoginPickerScreen extends HookConsumerWidget {
try {
await client.post(
'/auth/challenge/${challenge!.id}/factors/${factorPicked.value!.id}',
'/id/auth/challenge/${challenge!.id}/factors/${factorPicked.value!.id}',
data:
hintController.text.isNotEmpty
? jsonEncode(hintController.text)
@@ -555,7 +556,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
await client.post(
'/accounts/recovery/password',
'/id/accounts/recovery/password',
data: {'account': uname, 'captcha_token': captchaTk},
);
showInfoAlert('loginResetPasswordSent'.tr(), 'done'.tr());
@@ -573,7 +574,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
final resp = await client.post(
'/auth/challenge',
'/id/auth/challenge',
data: {
'account': uname,
'device_id': await getUdid(),
@@ -593,7 +594,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
final result = SnAuthChallenge.fromJson(resp.data);
onChallenge(result);
final factorResp = await client.get(
'/auth/challenge/${result.id}/factors',
'/id/auth/challenge/${result.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(
@@ -622,7 +623,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
if (context.mounted) showLoadingModal(context);
final resp = await client.post(
'/auth/login/apple/mobile',
'/id/auth/login/apple/mobile',
data: {
'identity_token': credential.identityToken!,
'authorization_code': credential.authorizationCode,
@@ -633,7 +634,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
final challenge = SnAuthChallenge.fromJson(resp.data);
onChallenge(challenge);
final factorResp = await client.get(
'/auth/challenge/${challenge.id}/factors',
'/id/auth/challenge/${challenge.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(
@@ -658,11 +659,11 @@ class _LoginLookupScreen extends HookConsumerWidget {
final client = ref.watch(apiClientProvider);
try {
final resp = await client.get('/auth/challenge/$challengeId');
final resp = await client.get('/id/auth/challenge/$challengeId');
final challenge = SnAuthChallenge.fromJson(resp.data);
onChallenge(challenge);
final factorResp = await client.get(
'/auth/challenge/${challenge.id}/factors',
'/id/auth/challenge/${challenge.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(

View File

@@ -120,7 +120,7 @@ class _OidcScreenState extends ConsumerState<OidcScreen> {
final queryParams = url.queryParameters;
// Check if we're on the token page
if (path.endsWith('/auth/callback')) {
if (path.endsWith('/id/auth/callback')) {
// Extract token from URL
final challenge = queryParams['challenge'];
// Return the token and close the webview

View File

@@ -165,7 +165,7 @@ class ChatRoomListTile extends HookConsumerWidget {
@riverpod
Future<List<SnChatRoom>> chatroomsJoined(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/chat');
final resp = await client.get('/sphere/chat');
return resp.data
.map((e) => SnChatRoom.fromJson(e))
.cast<SnChatRoom>()
@@ -233,7 +233,10 @@ class ChatListScreen extends HookConsumerWidget {
if (result == null) return;
final client = ref.read(apiClientProvider);
try {
await client.post('/chat/direct', data: {'related_user_id': result.id});
await client.post(
'/sphere/chat/direct',
data: {'related_user_id': result.id},
);
ref.invalidate(chatroomsJoinedProvider);
} catch (err) {
showErrorAlert(err);
@@ -319,7 +322,7 @@ class ChatListScreen extends HookConsumerWidget {
leading: const Icon(Symbols.add),
onTap: () {
Navigator.pop(context);
context.push('/chat/new').then((value) {
context.pushNamed('chatNew').then((value) {
if (value != null) {
ref.invalidate(chatroomsJoinedProvider);
}
@@ -400,7 +403,10 @@ class ChatListScreen extends HookConsumerWidget {
room: item,
isDirect: item.type == 1,
onTap: () {
context.push('/chat/${item.id}');
context.pushNamed(
'chatRoom',
pathParameters: {'id': item.id},
);
},
);
},
@@ -436,7 +442,7 @@ Future<SnChatRoom?> chatroom(Ref ref, String? identifier) async {
if (identifier == null) return null;
try {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/chat/$identifier');
final resp = await client.get('/sphere/chat/$identifier');
return SnChatRoom.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -451,7 +457,7 @@ Future<SnChatMember?> chatroomIdentity(Ref ref, String? identifier) async {
if (identifier == null) return null;
try {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/chat/$identifier/members/me');
final resp = await client.get('/sphere/chat/$identifier/members/me');
return SnChatMember.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -575,7 +581,7 @@ class EditChatScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
final resp = await client.request(
id == null ? '/chat' : '/chat/$id',
id == null ? '/sphere/chat' : '/sphere/chat/$id',
data: {
'name': nameController.text,
'description': descriptionController.text,
@@ -731,7 +737,7 @@ class EditChatScreen extends HookConsumerWidget {
@riverpod
Future<List<SnChatMember>> chatroomInvites(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/chat/invites');
final resp = await client.get('/sphere/chat/invites');
return resp.data
.map((e) => SnChatMember.fromJson(e))
.cast<SnChatMember>()
@@ -748,7 +754,7 @@ class _ChatInvitesSheet extends HookConsumerWidget {
Future<void> acceptInvite(SnChatMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post('/chat/invites/${invite.chatRoom!.id}/accept');
await client.post('/sphere/chat/invites/${invite.chatRoom!.id}/accept');
ref.invalidate(chatroomInvitesProvider);
ref.invalidate(chatroomsJoinedProvider);
} catch (err) {
@@ -759,7 +765,9 @@ class _ChatInvitesSheet extends HookConsumerWidget {
Future<void> declineInvite(SnChatMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post('/chat/invites/${invite.chatRoom!.id}/decline');
await client.post(
'/sphere/chat/invites/${invite.chatRoom!.id}/decline',
);
ref.invalidate(chatroomInvitesProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'chat.dart';
// RiverpodGenerator
// **************************************************************************
String _$chatroomsJoinedHash() => r'0c93fd3cb8fe5c87626836ced4f244bfa7598582';
String _$chatroomsJoinedHash() => r'3bb6389af07e81007680484d04bf5fe6f6c10571';
/// See also [chatroomsJoined].
@ProviderFor(chatroomsJoined)
@@ -25,7 +25,7 @@ final chatroomsJoinedProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ChatroomsJoinedRef = AutoDisposeFutureProviderRef<List<SnChatRoom>>;
String _$chatroomHash() => r'8dac7aaac50932e6dd213039102d43c1cf5f1d4e';
String _$chatroomHash() => r'2b17d94728026420d18d6c383d2400cf4a070913';
/// Copied from Dart SDK
class _SystemHash {
@@ -164,7 +164,7 @@ class _ChatroomProviderElement
String? get identifier => (origin as ChatroomProvider).identifier;
}
String _$chatroomIdentityHash() => r'ad6ad09b6fc4cf7c4abe146ea97f8e364a3d4fd0';
String _$chatroomIdentityHash() => r'35e19a5a3e31752c79b97ba0358a7ec8fb8f6e99';
/// See also [chatroomIdentity].
@ProviderFor(chatroomIdentity)
@@ -286,7 +286,7 @@ class _ChatroomIdentityProviderElement
String? get identifier => (origin as ChatroomIdentityProvider).identifier;
}
String _$chatroomInvitesHash() => r'c15f06c1e9c6074e6159d9d1f4404f31250ce523';
String _$chatroomInvitesHash() => r'5cd6391b09c5517ede19bacce43b45c8d71dd087';
/// See also [chatroomInvites].
@ProviderFor(chatroomInvites)

View File

@@ -687,7 +687,7 @@ class ChatRoomScreen extends HookConsumerWidget {
IconButton(
icon: const Icon(Icons.more_vert),
onPressed: () {
context.push('/chat/$id/detail');
context.pushNamed('chatDetail', pathParameters: {'id': id});
},
),
const Gap(8),

View File

@@ -389,7 +389,7 @@ class _ChatRoomActionMenu extends HookConsumerWidget {
if ((chatIdentity.value?.role ?? 0) >= 50)
PopupMenuItem(
onTap: () {
context.pushReplacement('/chat/$id/edit');
context.pushReplacement('/sphere/chat/$id/edit');
},
child: Row(
children: [
@@ -421,7 +421,7 @@ class _ChatRoomActionMenu extends HookConsumerWidget {
).then((confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/chat/$id');
client.delete('/sphere/chat/$id');
ref.invalidate(chatroomsJoinedProvider);
if (context.mounted) {
context.pop();
@@ -454,7 +454,7 @@ class _ChatRoomActionMenu extends HookConsumerWidget {
).then((confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/chat/$id/members/me');
client.delete('/sphere/chat/$id/members/me');
ref.invalidate(chatroomsJoinedProvider);
if (context.mounted) {
context.pop();

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
@@ -76,6 +75,130 @@ as String?,
}
/// Adds pattern-matching-related methods to [ChatRoomMemberState].
extension ChatRoomMemberStatePatterns on ChatRoomMemberState {
/// 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( _ChatRoomMemberState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _ChatRoomMemberState() 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( _ChatRoomMemberState value) $default,){
final _that = this;
switch (_that) {
case _ChatRoomMemberState():
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( _ChatRoomMemberState value)? $default,){
final _that = this;
switch (_that) {
case _ChatRoomMemberState() 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( List<SnChatMember> members, bool isLoading, int total, String? error)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ChatRoomMemberState() when $default != null:
return $default(_that.members,_that.isLoading,_that.total,_that.error);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( List<SnChatMember> members, bool isLoading, int total, String? error) $default,) {final _that = this;
switch (_that) {
case _ChatRoomMemberState():
return $default(_that.members,_that.isLoading,_that.total,_that.error);}
}
/// 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( List<SnChatMember> members, bool isLoading, int total, String? error)? $default,) {final _that = this;
switch (_that) {
case _ChatRoomMemberState() when $default != null:
return $default(_that.members,_that.isLoading,_that.total,_that.error);case _:
return null;
}
}
}
/// @nodoc

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});
},
),
);

View File

@@ -37,7 +37,7 @@ class CustomAppsScreen extends HookConsumerWidget {
IconButton(
icon: const Icon(Symbols.add),
onPressed: () {
context.push('/developers/$publisherName/apps/new');
context.pushNamed('developerAppNew', pathParameters: {'name': publisherName});
},
),
],
@@ -121,9 +121,7 @@ class CustomAppsScreen extends HookConsumerWidget {
],
onSelected: (value) {
if (value == 'edit') {
context.push(
'/developers/$publisherName/apps/${app.id}',
);
context.pushNamed('developerAppEdit', pathParameters: {'name': publisherName, 'id': app.id});
} else if (value == 'delete') {
showConfirmAlert(
'deleteCustomAppHint'.tr(),

View File

@@ -243,9 +243,7 @@ class DeveloperHubScreen extends HookConsumerWidget {
horizontal: 24,
),
onTap: () {
context.push(
'/developers/${currentDeveloper.value!.name}/apps',
);
context.pushNamed('developerApps', pathParameters: {'name': currentDeveloper.value!.name});
},
),
],

View File

@@ -145,7 +145,7 @@ class ExploreScreen extends HookConsumerWidget {
),
IconButton(
onPressed: () {
context.push('/feeds/articles');
context.pushNamed('articles');
},
icon: Icon(
Symbols.auto_stories,
@@ -155,7 +155,7 @@ class ExploreScreen extends HookConsumerWidget {
),
IconButton(
onPressed: () {
context.push('/posts/search');
context.pushNamed('postSearch');
},
icon: Icon(
Symbols.search,
@@ -175,7 +175,7 @@ class ExploreScreen extends HookConsumerWidget {
floatingActionButton: FloatingActionButton(
heroTag: Key("explore-page-fab"),
onPressed: () {
context.push('/posts/compose').then((value) {
context.pushNamed('postCompose').then((value) {
if (value != null) {
activitiesNotifier.forceRefresh();
}
@@ -400,7 +400,7 @@ class ActivityListNotifier extends _$ActivityListNotifier
};
final response = await client.get(
'/activities',
'/sphere/activities',
queryParameters: queryParameters,
);

View File

@@ -7,7 +7,7 @@ part of 'explore.dart';
// **************************************************************************
String _$activityListNotifierHash() =>
r'98b62fb9b958023d2c9e320af7ec1f1244836f49';
r'b75fd5c08d5f84ca433e16b7387d317ea72b91c9';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -36,7 +36,7 @@ class NotificationUnreadCountNotifier
try {
final client = ref.read(apiClientProvider);
final response = await client.get('/notifications/count');
final response = await client.get('/pusher/notifications/count');
return (response.data as num).toInt();
} catch (_) {
return 0;

View File

@@ -7,7 +7,7 @@ part of 'notification.dart';
// **************************************************************************
String _$notificationUnreadCountNotifierHash() =>
r'0d5b07caa625c24575c5581d5fcd3089effc2844';
r'd199abf0d16944587e747798399a267a790341f3';
/// See also [NotificationUnreadCountNotifier].
@ProviderFor(NotificationUnreadCountNotifier)

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
@@ -106,6 +105,130 @@ $SnPostCopyWith<$Res>? get forwardingTo {
}
/// Adds pattern-matching-related methods to [PostComposeInitialState].
extension PostComposeInitialStatePatterns on PostComposeInitialState {
/// 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( _PostComposeInitialState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PostComposeInitialState() 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( _PostComposeInitialState value) $default,){
final _that = this;
switch (_that) {
case _PostComposeInitialState():
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( _PostComposeInitialState value)? $default,){
final _that = this;
switch (_that) {
case _PostComposeInitialState() 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? title, String? description, String? content, List<UniversalFile> attachments, int? visibility, SnPost? replyingTo, SnPost? forwardingTo)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PostComposeInitialState() when $default != null:
return $default(_that.title,_that.description,_that.content,_that.attachments,_that.visibility,_that.replyingTo,_that.forwardingTo);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? title, String? description, String? content, List<UniversalFile> attachments, int? visibility, SnPost? replyingTo, SnPost? forwardingTo) $default,) {final _that = this;
switch (_that) {
case _PostComposeInitialState():
return $default(_that.title,_that.description,_that.content,_that.attachments,_that.visibility,_that.replyingTo,_that.forwardingTo);}
}
/// 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? title, String? description, String? content, List<UniversalFile> attachments, int? visibility, SnPost? replyingTo, SnPost? forwardingTo)? $default,) {final _that = this;
switch (_that) {
case _PostComposeInitialState() when $default != null:
return $default(_that.title,_that.description,_that.content,_that.attachments,_that.visibility,_that.replyingTo,_that.forwardingTo);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()

View File

@@ -17,7 +17,7 @@ part 'post_detail.g.dart';
@riverpod
Future<SnPost?> post(Ref ref, String id) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/posts/$id');
final resp = await client.get('/sphere/posts/$id');
return SnPost.fromJson(resp.data);
}

View File

@@ -6,7 +6,7 @@ part of 'post_detail.dart';
// RiverpodGenerator
// **************************************************************************
String _$postHash() => r'a5f66f47ed0eaef57e49518f6b764cdbfa725ad8';
String _$postHash() => r'66c2eb074c6d7467fef81cab70a13356e648e661';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -187,7 +187,9 @@ class PublisherProfileScreen extends HookConsumerWidget {
),
onTap: () {
Navigator.pop(context, true);
context.push('/account/${data.account?.name}');
if (data.account?.name != null) {
context.pushNamed('accountProfile', pathParameters: {'name': data.account!.name});
}
},
),
Expanded(

View File

@@ -43,7 +43,9 @@ Future<Color?> realmAppbarForegroundColor(Ref ref, String realmSlug) async {
Future<SnRealmMember?> realmIdentity(Ref ref, String realmSlug) async {
try {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get('/realms/$realmSlug/members/me');
final response = await apiClient.get(
'/sphere/realms/$realmSlug/members/me',
);
return SnRealmMember.fromJson(response.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -56,7 +58,7 @@ Future<SnRealmMember?> realmIdentity(Ref ref, String realmSlug) async {
@riverpod
Future<List<SnChatRoom>> realmChatRooms(Ref ref, String realmSlug) async {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get('/realms/$realmSlug/chat');
final response = await apiClient.get('/sphere/realms/$realmSlug/chat');
return (response.data as List).map((e) => SnChatRoom.fromJson(e)).toList();
}
@@ -211,7 +213,7 @@ class RealmDetailScreen extends HookConsumerWidget {
return ChatRoomListTile(
room: rooms[index],
onTap: () {
context.push('/chat/${rooms[index].id}');
context.pushNamed('chatRoom', pathParameters: {'id': rooms[index].id});
},
);
}, childCount: rooms.length),
@@ -249,7 +251,7 @@ class _RealmActionMenu extends HookConsumerWidget {
if (isModerator)
PopupMenuItem(
onTap: () {
context.pushReplacement('/realms/$realmSlug/edit');
context.pushReplacement('/sphere/realms/$realmSlug/edit');
},
child: Row(
children: [
@@ -284,7 +286,7 @@ class _RealmActionMenu extends HookConsumerWidget {
).then((confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/realms/$realmSlug');
client.delete('/sphere/realms/$realmSlug');
ref.invalidate(realmsJoinedProvider);
if (context.mounted) {
context.pop(true);
@@ -356,7 +358,7 @@ class _RealmActionMenu extends HookConsumerWidget {
).then((confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/realms/$realmSlug/members/me');
client.delete('/sphere/realms/$realmSlug/members/me');
ref.invalidate(realmsJoinedProvider);
if (context.mounted) {
context.pop(true);

View File

@@ -155,7 +155,7 @@ class _RealmAppbarForegroundColorProviderElement
(origin as RealmAppbarForegroundColorProvider).realmSlug;
}
String _$realmIdentityHash() => r'308d43eef8a6145c762d27bdf7e12e27149524db';
String _$realmIdentityHash() => r'c5e2977d243260947b919bc27146c134e34f0db1';
/// See also [realmIdentity].
@ProviderFor(realmIdentity)
@@ -276,7 +276,7 @@ class _RealmIdentityProviderElement
String get realmSlug => (origin as RealmIdentityProvider).realmSlug;
}
String _$realmChatRoomsHash() => r'8207c1e6f0922323967f208efeed027e943039cc';
String _$realmChatRoomsHash() => r'5f199906fb287b109e2a2d2a81dcb6675bdcb816';
/// See also [realmChatRooms].
@ProviderFor(realmChatRooms)

View File

@@ -28,7 +28,7 @@ part 'realms.g.dart';
@riverpod
Future<List<SnRealm>> realmsJoined(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/realms');
final resp = await client.get('/sphere/realms');
return resp.data.map((e) => SnRealm.fromJson(e)).cast<SnRealm>().toList();
}
@@ -48,7 +48,7 @@ class RealmListScreen extends HookConsumerWidget {
actions: [
IconButton(
icon: const Icon(Symbols.travel_explore),
onPressed: () => context.push('/discovery/realms'),
onPressed: () => context.pushNamed('discoveryRealms'),
),
IconButton(
icon: Badge(
@@ -81,7 +81,7 @@ class RealmListScreen extends HookConsumerWidget {
heroTag: const Key("realms-page-fab"),
child: const Icon(Symbols.add),
onPressed: () {
context.push('/realms/new').then((value) {
context.pushNamed('realmNew').then((value) {
if (value != null) {
ref.invalidate(realmsJoinedProvider);
}
@@ -108,7 +108,7 @@ class RealmListScreen extends HookConsumerWidget {
title: Text(value[item].name),
subtitle: Text(value[item].description),
onTap: () {
context.push('/realms/${value[item].slug}');
context.pushNamed('realmDetail', pathParameters: {'slug': value[item].slug});
},
contentPadding: const EdgeInsets.only(
left: 16,
@@ -139,7 +139,7 @@ class RealmListScreen extends HookConsumerWidget {
Future<SnRealm?> realm(Ref ref, String? identifier) async {
if (identifier == null) return null;
final client = ref.watch(apiClientProvider);
final resp = await client.get('/realms/$identifier');
final resp = await client.get('/sphere/realms/$identifier');
return SnRealm.fromJson(resp.data);
}
@@ -406,7 +406,7 @@ class EditRealmScreen extends HookConsumerWidget {
@riverpod
Future<List<SnRealmMember>> realmInvites(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/realms/invites');
final resp = await client.get('/sphere/realms/invites');
return resp.data
.map((e) => SnRealmMember.fromJson(e))
.cast<SnRealmMember>()
@@ -423,7 +423,9 @@ class _RealmInviteSheet extends HookConsumerWidget {
Future<void> acceptInvite(SnRealmMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post('/realms/invites/${invite.realm!.slug}/accept');
await client.post(
'/sphere/realms/invites/${invite.realm!.slug}/accept',
);
ref.invalidate(realmInvitesProvider);
ref.invalidate(realmsJoinedProvider);
} catch (err) {
@@ -434,7 +436,9 @@ class _RealmInviteSheet extends HookConsumerWidget {
Future<void> declineInvite(SnRealmMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post('/realms/invites/${invite.realm!.slug}/decline');
await client.post(
'/sphere/realms/invites/${invite.realm!.slug}/decline',
);
ref.invalidate(realmInvitesProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'realms.dart';
// RiverpodGenerator
// **************************************************************************
String _$realmsJoinedHash() => r'7c3367db97079365ec9973733cad9db6d8d50800';
String _$realmsJoinedHash() => r'e8083f02ffae450bba2470c31757675b4df32cd0';
/// See also [realmsJoined].
@ProviderFor(realmsJoined)
@@ -22,7 +22,7 @@ final realmsJoinedProvider = AutoDisposeFutureProvider<List<SnRealm>>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef RealmsJoinedRef = AutoDisposeFutureProviderRef<List<SnRealm>>;
String _$realmHash() => r'369d2f3dd80de9ab91457a772727ee89a0759c74';
String _$realmHash() => r'4650b17608a9ee14170ef20295eb14d295e909c9';
/// Copied from Dart SDK
class _SystemHash {
@@ -156,7 +156,7 @@ class _RealmProviderElement extends AutoDisposeFutureProviderElement<SnRealm?>
String? get identifier => (origin as RealmProvider).identifier;
}
String _$realmInvitesHash() => r'e265999a03932f8077fb95a619fd8849a215375a';
String _$realmInvitesHash() => r'ed73443c6423b92ed72982be2a93b7dcc7ce3945';
/// See also [realmInvites].
@ProviderFor(realmInvites)

View File

@@ -58,7 +58,7 @@ class _AbuseReportListScreenState extends ConsumerState<AbuseReportListScreen> {
),
child: InkWell(
onTap: () {
context.push('/safety/reports/me/${report.id}');
context.pushNamed('reportDetail', pathParameters: {'id': report.id});
},
child: Padding(
padding: const EdgeInsets.all(16.0),

View File

@@ -19,7 +19,7 @@ class TabsScreen extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
// final useHorizontalLayout = isWideScreen(context);
final currentLocation = GoRouterState.of(context).uri.toString();
// Update the current route provider whenever the location changes
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -52,17 +52,12 @@ class TabsScreen extends HookConsumerWidget {
),
];
final routes = [
'/',
'/chat',
'/realms',
'/account',
];
final routes = ['/', '/chat', '/realms', '/account'];
int getCurrentIndex() {
if (currentLocation.startsWith('/chat')) return 1;
if (currentLocation.startsWith('/realms')) return 2;
if (currentLocation.startsWith('/account')) return 3;
if (currentLocation.startsWith('/sphere/chat')) return 1;
if (currentLocation.startsWith('/sphere/realms')) return 2;
if (currentLocation.startsWith('/id/account')) return 3;
return 0; // Default to explore
}

View File

@@ -18,7 +18,7 @@ part 'wallet.g.dart';
Future<SnWallet?> walletCurrent(Ref ref) async {
try {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/wallets');
final resp = await apiClient.get('/id/wallets');
return SnWallet.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -81,7 +81,7 @@ class WalletScreen extends HookConsumerWidget {
Future<void> createWallet() async {
final client = ref.read(apiClientProvider);
try {
await client.post('/wallets');
await client.post('/id/wallets');
ref.invalidate(walletCurrentProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'wallet.dart';
// RiverpodGenerator
// **************************************************************************
String _$walletCurrentHash() => r'94e6f3776ce15679d17238e372660c365c9b1028';
String _$walletCurrentHash() => r'088505ce1a78901016a3bda05217f813ed3b44c6';
/// See also [walletCurrent].
@ProviderFor(walletCurrent)