💄 Better user agent

This commit is contained in:
LittleSheep 2024-09-16 11:57:16 +08:00
parent c18ce88993
commit 780f7c22bc
39 changed files with 140 additions and 113 deletions

View File

@ -71,7 +71,7 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
( (
label: 'bsCheckingServer', label: 'bsCheckingServer',
action: () async { action: () async {
final client = ServiceFinder.configureClient('dealer'); final client = await ServiceFinder.configureClient('dealer');
final resp = await client.get('/.well-known'); final resp = await client.get('/.well-known');
if (resp.statusCode != null && resp.statusCode != 200) { if (resp.statusCode != null && resp.statusCode != 200) {
setState(() { setState(() {

View File

@ -37,7 +37,7 @@ class StatusProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
return await client.get('/users/me/status'); return await client.get('/users/me/status');
} }
@ -56,7 +56,7 @@ class StatusProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final payload = { final payload = {
'type': type, 'type': type,
@ -85,7 +85,7 @@ class StatusProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.delete('/users/me/status'); final resp = await client.delete('/users/me/status');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {

View File

@ -115,14 +115,14 @@ class AuthProvider extends GetConnect {
return request; return request;
} }
GetConnect configureClient( Future<GetConnect> configureClient(
String service, { String service, {
timeout = const Duration(seconds: 5), timeout = const Duration(seconds: 5),
}) { }) async {
final client = GetConnect( final client = GetConnect(
maxAuthRetries: 3, maxAuthRetries: 3,
timeout: timeout, timeout: timeout,
userAgent: 'Solian/1.1', userAgent: await ServiceFinder.getUserAgent(),
sendUserAgent: true, sendUserAgent: true,
); );
client.httpClient.addAuthenticator(requestAuthenticator); client.httpClient.addAuthenticator(requestAuthenticator);
@ -204,7 +204,7 @@ class AuthProvider extends GetConnect {
Future<void> refreshUserProfile() async { Future<void> refreshUserProfile() async {
if (!isAuthorized.value) return; if (!isAuthorized.value) return;
final client = configureClient('auth'); final client = await configureClient('auth');
final resp = await client.get('/users/me'); final resp = await client.get('/users/me');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
throw RequestException(resp); throw RequestException(resp);

View File

@ -92,7 +92,7 @@ class ChatCallProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.post( final resp = await client.post(
'/channels/global/${channel.value!.alias}/calls/ongoing/token', '/channels/global/${channel.value!.alias}/calls/ongoing/token',

View File

@ -93,7 +93,7 @@ class AttachmentProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient( final client = await auth.configureClient(
'uc', 'uc',
timeout: const Duration(minutes: 3), timeout: const Duration(minutes: 3),
); );
@ -135,7 +135,7 @@ class AttachmentProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('uc'); final client = await auth.configureClient('uc');
final fileAlt = basename(path).contains('.') final fileAlt = basename(path).contains('.')
? basename(path).substring(0, basename(path).lastIndexOf('.')) ? basename(path).substring(0, basename(path).lastIndexOf('.'))
@ -173,7 +173,7 @@ class AttachmentProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient( final client = await auth.configureClient(
'uc', 'uc',
timeout: const Duration(minutes: 3), timeout: const Duration(minutes: 3),
); );
@ -198,7 +198,7 @@ class AttachmentProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('files'); final client = await auth.configureClient('files');
var resp = await client.put('/attachments/$id', { var resp = await client.put('/attachments/$id', {
'alt': alt, 'alt': alt,
@ -217,7 +217,7 @@ class AttachmentProvider extends GetConnect {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('files'); final client = await auth.configureClient('files');
var resp = await client.delete('/attachments/$id'); var resp = await client.delete('/attachments/$id');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {

View File

@ -33,7 +33,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get('/channels/$realm/$alias'); final resp = await client.get('/channels/$realm/$alias');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -48,7 +48,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get('/channels/$realm/$alias/me'); final resp = await client.get('/channels/$realm/$alias/me');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -63,7 +63,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get('/channels/$realm/$alias/calls/ongoing'); final resp = await client.get('/channels/$realm/$alias/calls/ongoing');
if (resp.statusCode == 404) { if (resp.statusCode == 404) {
@ -79,7 +79,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get('/channels/$scope'); final resp = await client.get('/channels/$scope');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -93,7 +93,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get('/channels/$realm/me/available'); final resp = await client.get('/channels/$realm/me/available');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -107,7 +107,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.post('/channels/$scope', payload); final resp = await client.post('/channels/$scope', payload);
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -132,7 +132,7 @@ class ChannelProvider extends GetxController {
if (related == null) return null; if (related == null) return null;
final prof = auth.userProfile.value!; final prof = auth.userProfile.value!;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.post('/channels/$scope/dm', { final resp = await client.post('/channels/$scope/dm', {
'alias': const Uuid().v4().replaceAll('-', '').substring(0, 12), 'alias': const Uuid().v4().replaceAll('-', '').substring(0, 12),
@ -153,7 +153,7 @@ class ChannelProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.put('/channels/$scope/$id', payload); final resp = await client.put('/channels/$scope/$id', payload);
if (resp.statusCode != 200) { if (resp.statusCode != 200) {

View File

@ -14,9 +14,9 @@ class PostProvider extends GetConnect {
GetConnect client; GetConnect client;
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.value) { if (auth.isAuthorized.value) {
client = auth.configureClient('co'); client = await auth.configureClient('co');
} else { } else {
client = ServiceFinder.configureClient('co'); client = await ServiceFinder.configureClient('co');
} }
final resp = await client.get('/whats-new?pivot=$pivot'); final resp = await client.get('/whats-new?pivot=$pivot');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -36,9 +36,9 @@ class PostProvider extends GetConnect {
if (realm != null) 'realm=$realm', if (realm != null) 'realm=$realm',
]; ];
if (auth.isAuthorized.value) { if (auth.isAuthorized.value) {
client = auth.configureClient('co'); client = await auth.configureClient('co');
} else { } else {
client = ServiceFinder.configureClient('co'); client = await ServiceFinder.configureClient('co');
} }
final resp = await client.get( final resp = await client.get(
channel == null channel == null
@ -60,7 +60,7 @@ class PostProvider extends GetConnect {
'take=${10}', 'take=${10}',
'offset=$page', 'offset=$page',
]; ];
final client = auth.configureClient('interactive'); final client = await auth.configureClient('interactive');
final resp = await client.get('/posts/drafts?${queries.join('&')}'); final resp = await client.get('/posts/drafts?${queries.join('&')}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
throw RequestException(resp); throw RequestException(resp);

View File

@ -25,7 +25,7 @@ class RealmProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.get('/realms/$alias'); final resp = await client.get('/realms/$alias');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -39,7 +39,7 @@ class RealmProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.get('/realms/me/available'); final resp = await client.get('/realms/me/available');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {

View File

@ -10,7 +10,7 @@ class DailySignProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('id'); final client = await auth.configureClient('id');
final resp = await client.get('/daily?take=$take'); final resp = await client.get('/daily?take=$take');
if (resp.statusCode != 200 && resp.statusCode != 404) { if (resp.statusCode != 200 && resp.statusCode != 404) {
@ -30,7 +30,7 @@ class DailySignProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('id'); final client = await auth.configureClient('id');
final resp = await client.get('/daily/today'); final resp = await client.get('/daily/today');
if (resp.statusCode != 200 && resp.statusCode != 404) { if (resp.statusCode != 200 && resp.statusCode != 404) {
@ -46,7 +46,7 @@ class DailySignProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); if (auth.isAuthorized.isFalse) throw const UnauthorizedException();
final client = auth.configureClient('id'); final client = await auth.configureClient('id');
final resp = await client.post('/daily', {}); final resp = await client.post('/daily', {});
if (resp.statusCode != 200) { if (resp.statusCode != 200) {

View File

@ -12,7 +12,7 @@ class MessagesFetchingProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return null; if (auth.isAuthorized.isFalse) return null;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get( final resp = await client.get(
'/whats-new?pivot=$pivot&take=$take', '/whats-new?pivot=$pivot&take=$take',
@ -33,7 +33,7 @@ class MessagesFetchingProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return null; if (auth.isAuthorized.isFalse) return null;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get( final resp = await client.get(
'/channels/$scope/${channel.alias}/events/$id', '/channels/$scope/${channel.alias}/events/$id',
@ -57,7 +57,7 @@ class MessagesFetchingProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return null; if (auth.isAuthorized.isFalse) return null;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.get( final resp = await client.get(
'/channels/$scope/${channel.alias}/events?take=$take&offset=$offset', '/channels/$scope/${channel.alias}/events?take=$take&offset=$offset',

View File

@ -12,7 +12,7 @@ class LinkExpandProvider extends GetxController {
log('[LinkExpander] Expanding link... $url'); log('[LinkExpander] Expanding link... $url');
final target = utf8.fuse(base64).encode(url); final target = utf8.fuse(base64).encode(url);
if (_cachedResponse.containsKey(target)) return _cachedResponse[target]; if (_cachedResponse.containsKey(target)) return _cachedResponse[target];
final client = ServiceFinder.configureClient('dealer'); final client = await ServiceFinder.configureClient('dealer');
final resp = await client.get('/api/links/$target'); final resp = await client.get('/api/links/$target');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
log('Unable to expand link ($url), status: ${resp.statusCode}, response: ${resp.body}'); log('Unable to expand link ($url), status: ${resp.statusCode}, response: ${resp.body}');

View File

@ -26,21 +26,21 @@ class RelationshipProvider extends GetxController {
return _friends.any((x) => x.relatedId == account.id); return _friends.any((x) => x.relatedId == account.id);
} }
Future<Response> listRelation() { Future<Response> listRelation() async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
return client.get('/users/me/relations'); return client.get('/users/me/relations');
} }
Future<Response> listRelationWithStatus(int status) { Future<Response> listRelationWithStatus(int status) async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
return client.get('/users/me/relations?status=$status'); return client.get('/users/me/relations?status=$status');
} }
Future<Response> makeFriend(String username) async { Future<Response> makeFriend(String username) async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.post('/users/me/relations?related=$username', {}); final resp = await client.post('/users/me/relations?related=$username', {});
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
throw RequestException(resp); throw RequestException(resp);
@ -52,7 +52,7 @@ class RelationshipProvider extends GetxController {
Future<Response> handleRelation( Future<Response> handleRelation(
Relationship relationship, bool doAccept) async { Relationship relationship, bool doAccept) async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.post( final resp = await client.post(
'/users/me/relations/${relationship.relatedId}/${doAccept ? 'accept' : 'decline'}', '/users/me/relations/${relationship.relatedId}/${doAccept ? 'accept' : 'decline'}',
{}, {},
@ -66,7 +66,7 @@ class RelationshipProvider extends GetxController {
Future<Response> editRelation(Relationship relationship, int status) async { Future<Response> editRelation(Relationship relationship, int status) async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.patch( final resp = await client.patch(
'/users/me/relations/${relationship.relatedId}', '/users/me/relations/${relationship.relatedId}',
{'status': status}, {'status': status},

View File

@ -11,7 +11,7 @@ class StickerProvider extends GetxController {
availableStickers.clear(); availableStickers.clear();
aliasImageMapping.clear(); aliasImageMapping.clear();
final client = ServiceFinder.configureClient('files'); final client = await ServiceFinder.configureClient('files');
final resp = await client.get( final resp = await client.get(
'/stickers/manifest?take=100', '/stickers/manifest?take=100',
); );

View File

@ -138,7 +138,7 @@ class WebSocketProvider extends GetxController {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.get('/notifications?skip=0&take=100'); final resp = await client.get('/notifications?skip=0&take=100');
if (resp.statusCode == 200) { if (resp.statusCode == 200) {
@ -182,7 +182,7 @@ class WebSocketProvider extends GetxController {
} }
log('Device Push Token is $token'); log('Device Push Token is $token');
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.post('/notifications/subscribe', { final resp = await client.post('/notifications/subscribe', {
'provider': provider, 'provider': provider,

View File

@ -205,7 +205,6 @@ class _ActionCard extends StatelessWidget {
final Function onTap; final Function onTap;
const _ActionCard({ const _ActionCard({
super.key,
required this.onTap, required this.onTap,
required this.title, required this.title,
required this.caption, required this.caption,

View File

@ -31,7 +31,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
} }
if (markList.isNotEmpty) { if (markList.isNotEmpty) {
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
await client.put('/notifications/read', {'messages': markList}); await client.put('/notifications/read', {'messages': markList});
} }
@ -53,7 +53,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
await client.put('/notifications/read/${element.id}', {}); await client.put('/notifications/read/${element.id}', {});

View File

@ -126,7 +126,7 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
return; return;
} }
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.put( final resp = await client.put(
'/users/me/$position', '/users/me/$position',
@ -148,7 +148,7 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
_birthday?.toIso8601String(); _birthday?.toIso8601String();
final resp = await client.put( final resp = await client.put(

View File

@ -46,7 +46,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
Future<void> _getUserinfo() async { Future<void> _getUserinfo() async {
setState(() => _isBusy = true); setState(() => _isBusy = true);
var client = ServiceFinder.configureClient('auth'); var client = await ServiceFinder.configureClient('auth');
var resp = await client.get('/users/${widget.name}'); var resp = await client.get('/users/${widget.name}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
context.showErrorDialog(resp.bodyString).then((_) { context.showErrorDialog(resp.bodyString).then((_) {
@ -56,7 +56,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
_userinfo = Account.fromJson(resp.body); _userinfo = Account.fromJson(resp.body);
} }
client = ServiceFinder.configureClient('interactive'); client = await ServiceFinder.configureClient('interactive');
resp = await client.get('/users/${widget.name}'); resp = await client.get('/users/${widget.name}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
context.showErrorDialog(resp.bodyString).then((_) { context.showErrorDialog(resp.bodyString).then((_) {
@ -71,7 +71,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
} }
Future<void> getPinnedPosts() async { Future<void> getPinnedPosts() async {
final client = 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) {
context.showErrorDialog(resp.bodyString).then((_) { context.showErrorDialog(resp.bodyString).then((_) {
@ -95,7 +95,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
_relationshipProvider = Get.find(); _relationshipProvider = Get.find();
_postController = PostListController(author: widget.name); _postController = PostListController(author: widget.name);
_albumPagingController.addPageRequestListener((pageKey) async { _albumPagingController.addPageRequestListener((pageKey) async {
final client = ServiceFinder.configureClient('files'); final client = await ServiceFinder.configureClient('files');
final resp = await client.get( final resp = await client.get(
'/attachments?take=10&offset=$pageKey&author=${widget.name}&original=true', '/attachments?take=10&offset=$pageKey&author=${widget.name}&original=true',
); );

View File

@ -48,7 +48,7 @@ class _StickerScreenState extends State<StickerScreen> {
); );
if (confirm != true) return false; if (confirm != true) return false;
final client = auth.configureClient('files'); final client = await auth.configureClient('files');
final resp = await client.delete('/stickers/${item.id}'); final resp = await client.delete('/stickers/${item.id}');
return resp.statusCode == 200; return resp.statusCode == 200;
@ -107,7 +107,7 @@ class _StickerScreenState extends State<StickerScreen> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final name = auth.userProfile.value!['name']; final name = auth.userProfile.value!['name'];
_pagingController.addPageRequestListener((pageKey) async { _pagingController.addPageRequestListener((pageKey) async {
final client = ServiceFinder.configureClient('files'); final client = await ServiceFinder.configureClient('files');
final resp = await client.get( final resp = await client.get(
'/stickers/manifest?take=10&offset=$pageKey&author=$name', '/stickers/manifest?take=10&offset=$pageKey&author=$name',
); );

View File

@ -49,7 +49,7 @@ class _SignInScreenState extends State<SignInScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
final lookupResp = await client.get('/users/lookup?probe=$username'); final lookupResp = await client.get('/users/lookup?probe=$username');
if (lookupResp.statusCode != 200) { if (lookupResp.statusCode != 200) {
context.showErrorDialog(lookupResp.bodyString); context.showErrorDialog(lookupResp.bodyString);
@ -74,7 +74,7 @@ class _SignInScreenState extends State<SignInScreen> {
final username = _usernameController.value.text; final username = _usernameController.value.text;
if (username.isEmpty) return; if (username.isEmpty) return;
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
setState(() => _isBusy = true); setState(() => _isBusy = true);
@ -114,7 +114,7 @@ class _SignInScreenState extends State<SignInScreen> {
void _performGetFactorCode() async { void _performGetFactorCode() async {
if (_factorPicked == null) return; if (_factorPicked == null) return;
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
setState(() => _isBusy = true); setState(() => _isBusy = true);
@ -147,7 +147,7 @@ class _SignInScreenState extends State<SignInScreen> {
final password = _passwordController.value.text; final password = _passwordController.value.text;
if (password.isEmpty) return; if (password.isEmpty) return;
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
setState(() => _isBusy = true); setState(() => _isBusy = true);
@ -288,7 +288,9 @@ class _SignInScreenState extends State<SignInScreen> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
TextButton( TextButton(
onPressed: _isBusy ? null : () => _previousStep(), onPressed: (_isBusy || _period > 1)
? null
: () => _previousStep(),
style: style:
TextButton.styleFrom(foregroundColor: Colors.grey), TextButton.styleFrom(foregroundColor: Colors.grey),
child: Row( child: Row(

View File

@ -28,7 +28,7 @@ class _SignUpScreenState extends State<SignUpScreen> {
nickname.isEmpty || nickname.isEmpty ||
password.isEmpty) return; password.isEmpty) return;
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
final resp = await client.post('/users', { final resp = await client.post('/users', {
'name': username, 'name': username,

View File

@ -97,7 +97,6 @@ class _ChannelChatScreenState extends State<ChannelChatScreen>
setState(() => _ongoingCall = Call.fromJson(resp.body)); setState(() => _ongoingCall = Call.fromJson(resp.body));
} }
} catch (e) { } catch (e) {
print((e as dynamic).stackTrace);
context.showErrorDialog(e); context.showErrorDialog(e);
} }

View File

@ -79,7 +79,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client final resp = await client
.put('/channels/${widget.realm}/${widget.channel.alias}/members/me', { .put('/channels/${widget.realm}/${widget.channel.alias}/members/me', {

View File

@ -75,7 +75,7 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('interactive'); final client = await auth.configureClient('interactive');
Response resp; Response resp;
if (widget.edit != null) { if (widget.edit != null) {

View File

@ -43,7 +43,7 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final payload = { final payload = {
'alias': _aliasController.value.text.toLowerCase(), 'alias': _aliasController.value.text.toLowerCase(),

View File

@ -1,28 +1,58 @@
import 'package:device_info_plus/device_info_plus.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:solian/platform.dart';
abstract class ServiceFinder { abstract class ServiceFinder {
static const bool devFlag = true; static const bool devFlag = false;
static const String dealerUrl = static const String dealerUrl =
devFlag ? 'http://localhost:8442' : 'https://api.sn.solsynth.dev'; devFlag ? 'http://localhost:8442' : 'https://api.sn.solsynth.dev';
static const String capitalUrl =
devFlag ? 'http://localhost:8444' : 'https://solsynth.dev';
static String buildUrl(String serviceName, String? append) { static String buildUrl(String serviceName, String? append) {
append ??= ''; append ??= '';
if (serviceName == 'dealer') { if (serviceName == 'dealer') {
return '$dealerUrl$append'; return '$dealerUrl$append';
} else if (serviceName == 'capital') {
return '$capitalUrl$append';
} }
return '$dealerUrl/cgi/$serviceName$append'; return '$dealerUrl/cgi/$serviceName$append';
} }
static GetConnect configureClient(String serviceName, static Future<String> getUserAgent() async {
{timeout = const Duration(seconds: 5)}) { final String platformInfo;
if (PlatformInfo.isAndroid) {
final deviceInfo = await DeviceInfoPlugin().androidInfo;
platformInfo =
'Android; ${deviceInfo.brand} ${deviceInfo.model}; ${deviceInfo.id}';
} else if (PlatformInfo.isIOS) {
final deviceInfo = await DeviceInfoPlugin().iosInfo;
platformInfo = 'iOS; ${deviceInfo.model}; ${deviceInfo.name}';
} else if (PlatformInfo.isMacOS) {
final deviceInfo = await DeviceInfoPlugin().macOsInfo;
platformInfo = 'MacOS; ${deviceInfo.model}; ${deviceInfo.hostName}';
} else if (PlatformInfo.isWindows) {
final deviceInfo = await DeviceInfoPlugin().windowsInfo;
platformInfo =
'Windows NT; ${deviceInfo.productName}; ${deviceInfo.computerName}';
} else if (PlatformInfo.isLinux) {
final deviceInfo = await DeviceInfoPlugin().linuxInfo;
platformInfo = 'Linux; ${deviceInfo.prettyName}';
} else if (PlatformInfo.isWeb) {
final deviceInfo = await DeviceInfoPlugin().webBrowserInfo;
platformInfo = 'Web; ${deviceInfo.vendor}';
} else {
platformInfo = 'Unknown';
}
final packageInfo = await PackageInfo.fromPlatform();
return 'Solian/${packageInfo.version}+${packageInfo.buildNumber} ($platformInfo)';
}
static Future<GetConnect> configureClient(String serviceName,
{timeout = const Duration(seconds: 5)}) async {
final client = GetConnect( final client = GetConnect(
timeout: timeout, timeout: timeout,
userAgent: 'Solian/1.1', userAgent: await getUserAgent(),
sendUserAgent: true, sendUserAgent: true,
); );
client.httpClient.baseUrl = buildUrl(serviceName, null); client.httpClient.baseUrl = buildUrl(serviceName, null);

View File

@ -26,7 +26,7 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
try { try {
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
final resp = await client.get('/users/${widget.name}'); final resp = await client.get('/users/${widget.name}');
if (resp.statusCode == 200) { if (resp.statusCode == 200) {
setState(() { setState(() {

View File

@ -36,16 +36,13 @@ class _AccountSelectorState extends State<AccountSelector> {
_revertSelectedUsers() async { _revertSelectedUsers() async {
if (widget.initialSelection?.isEmpty ?? true) return; if (widget.initialSelection?.isEmpty ?? true) return;
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
final idQuery = widget.initialSelection!.join(','); final idQuery = widget.initialSelection!.join(',');
final resp = await client.get('/users?id=$idQuery'); final resp = await client.get('/users?id=$idQuery');
setState(() { setState(() {
_selectedUsers.addAll( _selectedUsers.addAll(
resp.body resp.body.map((e) => Account.fromJson(e)).toList().cast<Account>(),
.map((e) => Account.fromJson(e))
.toList()
.cast<Account>(),
); );
}); });
} }
@ -73,7 +70,7 @@ class _AccountSelectorState extends State<AccountSelector> {
if (_probeController.text.isEmpty) return; if (_probeController.text.isEmpty) return;
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.get( final resp = await client.get(
'/users/search?probe=${_probeController.text}', '/users/search?probe=${_probeController.text}',
); );
@ -156,7 +153,8 @@ class _AccountSelectorState extends State<AccountSelector> {
} }
setState(() { setState(() {
final idx = _selectedUsers.indexWhere((x) => x.id == element.id); final idx = _selectedUsers
.indexWhere((x) => x.id == element.id);
if (idx != -1) { if (idx != -1) {
_selectedUsers.removeAt(idx); _selectedUsers.removeAt(idx);
} else { } else {

View File

@ -29,10 +29,10 @@ class _ChannelDeletionDialogState extends State<ChannelDeletionDialog> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client final resp =
.delete('/channels/${widget.realm}/${widget.channel.id}'); await client.delete('/channels/${widget.realm}/${widget.channel.id}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
context.showErrorDialog(resp.bodyString); context.showErrorDialog(resp.bodyString);
} else if (Navigator.canPop(context)) { } else if (Navigator.canPop(context)) {
@ -48,7 +48,7 @@ class _ChannelDeletionDialogState extends State<ChannelDeletionDialog> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.delete( final resp = await client.delete(
'/channels/${widget.realm}/${widget.channel.alias}/members/me', '/channels/${widget.realm}/${widget.channel.alias}/members/me',
@ -69,11 +69,11 @@ class _ChannelDeletionDialogState extends State<ChannelDeletionDialog> {
? 'channelDeletionConfirm'.tr ? 'channelDeletionConfirm'.tr
: 'channelLeaveConfirm'.tr), : 'channelLeaveConfirm'.tr),
content: Text( content: Text(
widget.isOwned ? widget.isOwned
'channelDeletionConfirmCaption' ? 'channelDeletionConfirmCaption'
.trParams({'channel': '#${widget.channel.alias}'}) : .trParams({'channel': '#${widget.channel.alias}'})
'channelLeaveConfirmCaption' : 'channelLeaveConfirmCaption'
.trParams({'channel': '#${widget.channel.alias}'}), .trParams({'channel': '#${widget.channel.alias}'}),
), ),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(

View File

@ -39,7 +39,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
void getMembers() async { void getMembers() async {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = ServiceFinder.configureClient('messaging'); final client = await ServiceFinder.configureClient('messaging');
final resp = await client final resp = await client
.get('/channels/${widget.realm}/${widget.channel.alias}/members'); .get('/channels/${widget.realm}/${widget.channel.alias}/members');
@ -75,7 +75,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.post( final resp = await client.post(
'/channels/${widget.realm}/${widget.channel.alias}/members', '/channels/${widget.realm}/${widget.channel.alias}/members',
@ -96,7 +96,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
final resp = await client.request( final resp = await client.request(
'/channels/${widget.realm}/${widget.channel.alias}/members', '/channels/${widget.realm}/${widget.channel.alias}/members',

View File

@ -33,7 +33,7 @@ class _ChatCallButtonState extends State<ChatCallButton> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
setState(() => _isBusy = true); setState(() => _isBusy = true);
@ -57,7 +57,7 @@ class _ChatCallButtonState extends State<ChatCallButton> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
setState(() => _isBusy = true); setState(() => _isBusy = true);

View File

@ -30,7 +30,7 @@ class _ChatEventDeletionDialogState extends State<ChatEventDeletionDialog> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('messaging'); final client = await auth.configureClient('messaging');
setState(() => _isBusy = true); setState(() => _isBusy = true);

View File

@ -118,7 +118,7 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
final mentionedUserNames = _findMentionedUsers(_textController.text); final mentionedUserNames = _findMentionedUsers(_textController.text);
final mentionedUserIds = List<int>.empty(growable: true); final mentionedUserIds = List<int>.empty(growable: true);
var client = auth.configureClient('auth'); var client = await auth.configureClient('auth');
if (mentionedUserNames.isNotEmpty) { if (mentionedUserNames.isNotEmpty) {
resp = await client.get('/users?name=${mentionedUserNames.join(',')}'); resp = await client.get('/users?name=${mentionedUserNames.join(',')}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -131,7 +131,7 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
} }
} }
client = auth.configureClient('messaging'); client = await auth.configureClient('messaging');
if (_textController.text.trim().isEmpty && _attachments.isEmpty) return; if (_textController.text.trim().isEmpty && _attachments.isEmpty) return;
@ -432,7 +432,7 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
final userSearch = userMatch[1]!.toLowerCase(); final userSearch = userMatch[1]!.toLowerCase();
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.get( final resp = await client.get(
'/users/search?probe=$userSearch', '/users/search?probe=$userSearch',
); );

View File

@ -35,7 +35,7 @@ class _TagsFieldState extends State<TagsField> {
Future<List<String>?> _searchTags(String probe) async { Future<List<String>?> _searchTags(String probe) async {
_currentSearchProbe = probe; _currentSearchProbe = probe;
final client = ServiceFinder.configureClient('interactive'); final client = await ServiceFinder.configureClient('interactive');
final resp = await client.get( final resp = await client.get(
'/tags?take=10&probe=$_currentSearchProbe', '/tags?take=10&probe=$_currentSearchProbe',
); );

View File

@ -192,7 +192,7 @@ class _PostActionState extends State<PostAction> {
: 'unpinPost'.tr, : 'unpinPost'.tr,
), ),
onTap: () async { onTap: () async {
final client = Get.find<AuthProvider>() final client = await Get.find<AuthProvider>()
.configureClient('interactive'); .configureClient('interactive');
await client.post('/posts/${widget.item.id}/pin', {}); await client.post('/posts/${widget.item.id}/pin', {});
Navigator.pop(context, true); Navigator.pop(context, true);
@ -254,7 +254,7 @@ class _PostDeletionDialogState extends State<PostDeletionDialog> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('interactive'); final client = await auth.configureClient('interactive');
setState(() => _isBusy = true); setState(() => _isBusy = true);
final resp = await client.delete('/posts/${widget.item.id}'); final resp = await client.delete('/posts/${widget.item.id}');

View File

@ -49,7 +49,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
if (_isSubmitting) return; if (_isSubmitting) return;
if (auth.isAuthorized.isFalse) return; if (auth.isAuthorized.isFalse) return;
final client = auth.configureClient('interactive'); final client = await auth.configureClient('interactive');
setState(() => _isSubmitting = true); setState(() => _isSubmitting = true);

View File

@ -27,7 +27,7 @@ class _RealmDeletionDialogState extends State<RealmDeletionDialog> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.delete('/realms/${widget.realm.id}'); final resp = await client.delete('/realms/${widget.realm.id}');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
@ -45,10 +45,9 @@ class _RealmDeletionDialogState extends State<RealmDeletionDialog> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = final resp = await client.delete('/realms/${widget.realm.id}/members/me');
await client.delete('/realms/${widget.realm.id}/members/me');
if (resp.statusCode != 200) { if (resp.statusCode != 200) {
context.showErrorDialog(resp.bodyString); context.showErrorDialog(resp.bodyString);
} else if (Navigator.canPop(context)) { } else if (Navigator.canPop(context)) {

View File

@ -37,7 +37,7 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
void getMembers() async { void getMembers() async {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = ServiceFinder.configureClient('auth'); final client = await ServiceFinder.configureClient('auth');
final resp = await client.get('/realms/${widget.realm.alias}/members'); final resp = await client.get('/realms/${widget.realm.alias}/members');
if (resp.statusCode == 200) { if (resp.statusCode == 200) {
@ -72,7 +72,7 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.post( final resp = await client.post(
'/realms/${widget.realm.alias}/members', '/realms/${widget.realm.alias}/members',
@ -93,7 +93,7 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
final client = auth.configureClient('auth'); final client = await auth.configureClient('auth');
final resp = await client.request( final resp = await client.request(
'/realms/${widget.realm.alias}/members', '/realms/${widget.realm.alias}/members',

View File

@ -63,7 +63,7 @@ class _StickerUploadDialogState extends State<StickerUploadDialog> {
setState(() => _isBusy = true); setState(() => _isBusy = true);
Response resp; Response resp;
final client = auth.configureClient('files'); final client = await auth.configureClient('files');
if (widget.edit == null) { if (widget.edit == null) {
resp = await client.post('/stickers', { resp = await client.post('/stickers', {
'name': _nameController.text, 'name': _nameController.text,