⬆️ Upgrade to support latest version of server
This commit is contained in:
parent
286dd8193d
commit
da265da61d
@ -8,9 +8,8 @@ import 'package:sentry_flutter/sentry_flutter.dart';
|
|||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
import 'package:solian/firebase_options.dart';
|
import 'package:solian/firebase_options.dart';
|
||||||
import 'package:solian/platform.dart';
|
import 'package:solian/platform.dart';
|
||||||
import 'package:solian/providers/account.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/providers/chat.dart';
|
|
||||||
import 'package:solian/providers/content/attachment.dart';
|
import 'package:solian/providers/content/attachment.dart';
|
||||||
import 'package:solian/providers/content/call.dart';
|
import 'package:solian/providers/content/call.dart';
|
||||||
import 'package:solian/providers/content/channel.dart';
|
import 'package:solian/providers/content/channel.dart';
|
||||||
@ -100,8 +99,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
Get.lazyPut(() => FriendProvider());
|
Get.lazyPut(() => FriendProvider());
|
||||||
Get.lazyPut(() => FeedProvider());
|
Get.lazyPut(() => FeedProvider());
|
||||||
Get.lazyPut(() => AttachmentProvider());
|
Get.lazyPut(() => AttachmentProvider());
|
||||||
Get.lazyPut(() => ChatProvider());
|
Get.lazyPut(() => WebSocketProvider());
|
||||||
Get.lazyPut(() => AccountProvider());
|
|
||||||
Get.lazyPut(() => StatusProvider());
|
Get.lazyPut(() => StatusProvider());
|
||||||
Get.lazyPut(() => ChannelProvider());
|
Get.lazyPut(() => ChannelProvider());
|
||||||
Get.lazyPut(() => RealmProvider());
|
Get.lazyPut(() => RealmProvider());
|
||||||
@ -109,13 +107,12 @@ class SolianApp extends StatelessWidget {
|
|||||||
|
|
||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (await auth.isAuthorized) {
|
if (await auth.isAuthorized) {
|
||||||
Get.find<AccountProvider>().connect();
|
Get.find<WebSocketProvider>().connect();
|
||||||
Get.find<ChatProvider>().connect();
|
|
||||||
|
|
||||||
Get.find<ChannelProvider>().refreshAvailableChannel();
|
Get.find<ChannelProvider>().refreshAvailableChannel();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Get.find<AccountProvider>().registerPushNotifications();
|
Get.find<WebSocketProvider>().registerPushNotifications();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showSnackbar(
|
context.showSnackbar(
|
||||||
'pushNotifyRegisterFailed'.trParams({'reason': err.toString()}),
|
'pushNotifyRegisterFailed'.trParams({'reason': err.toString()}),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
import 'package:solian/models/feed.dart';
|
import 'package:solian/models/feed.dart';
|
||||||
|
import 'package:solian/models/post.dart';
|
||||||
import 'package:solian/models/realm.dart';
|
import 'package:solian/models/realm.dart';
|
||||||
|
|
||||||
class Article {
|
class Article {
|
||||||
@ -20,8 +21,7 @@ class Article {
|
|||||||
bool? isDraft;
|
bool? isDraft;
|
||||||
int authorId;
|
int authorId;
|
||||||
Account author;
|
Account author;
|
||||||
int reactionCount;
|
PostMetric? metric;
|
||||||
Map<String, int> reactionList;
|
|
||||||
|
|
||||||
Article({
|
Article({
|
||||||
required this.id,
|
required this.id,
|
||||||
@ -41,8 +41,7 @@ class Article {
|
|||||||
required this.isDraft,
|
required this.isDraft,
|
||||||
required this.authorId,
|
required this.authorId,
|
||||||
required this.author,
|
required this.author,
|
||||||
required this.reactionCount,
|
required this.metric,
|
||||||
required this.reactionList,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Article.fromJson(Map<String, dynamic> json) => Article(
|
factory Article.fromJson(Map<String, dynamic> json) => Article(
|
||||||
@ -72,15 +71,8 @@ class Article {
|
|||||||
isDraft: json['is_draft'],
|
isDraft: json['is_draft'],
|
||||||
authorId: json['author_id'],
|
authorId: json['author_id'],
|
||||||
author: Account.fromJson(json['author']),
|
author: Account.fromJson(json['author']),
|
||||||
reactionCount: json['reaction_count'],
|
metric:
|
||||||
reactionList: json['reaction_list'] != null
|
json['metric'] != null ? PostMetric.fromJson(json['metric']) : null,
|
||||||
? json['reaction_list']
|
|
||||||
.map((key, value) => MapEntry(
|
|
||||||
key,
|
|
||||||
int.tryParse(value.toString()) ??
|
|
||||||
(value is double ? value.toInt() : null)))
|
|
||||||
.cast<String, int>()
|
|
||||||
: {},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@ -101,7 +93,6 @@ class Article {
|
|||||||
'is_draft': isDraft,
|
'is_draft': isDraft,
|
||||||
'author_id': authorId,
|
'author_id': authorId,
|
||||||
'author': author.toJson(),
|
'author': author.toJson(),
|
||||||
'reaction_count': reactionCount,
|
'metric': metric?.toJson(),
|
||||||
'reaction_list': reactionList,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,7 @@ class Post {
|
|||||||
bool? isDraft;
|
bool? isDraft;
|
||||||
int authorId;
|
int authorId;
|
||||||
Account author;
|
Account author;
|
||||||
int replyCount;
|
PostMetric? metric;
|
||||||
int reactionCount;
|
|
||||||
Map<String, int> reactionList;
|
|
||||||
|
|
||||||
Post({
|
Post({
|
||||||
required this.id,
|
required this.id,
|
||||||
@ -48,9 +46,7 @@ class Post {
|
|||||||
required this.isDraft,
|
required this.isDraft,
|
||||||
required this.authorId,
|
required this.authorId,
|
||||||
required this.author,
|
required this.author,
|
||||||
required this.replyCount,
|
required this.metric,
|
||||||
required this.reactionCount,
|
|
||||||
required this.reactionList,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Post.fromJson(Map<String, dynamic> json) => Post(
|
factory Post.fromJson(Map<String, dynamic> json) => Post(
|
||||||
@ -85,16 +81,8 @@ class Post {
|
|||||||
isDraft: json['is_draft'],
|
isDraft: json['is_draft'],
|
||||||
authorId: json['author_id'],
|
authorId: json['author_id'],
|
||||||
author: Account.fromJson(json['author']),
|
author: Account.fromJson(json['author']),
|
||||||
replyCount: json['reply_count'],
|
metric:
|
||||||
reactionCount: json['reaction_count'],
|
json['metric'] != null ? PostMetric.fromJson(json['metric']) : null,
|
||||||
reactionList: json['reaction_list'] != null
|
|
||||||
? json['reaction_list']
|
|
||||||
.map((key, value) => MapEntry(
|
|
||||||
key,
|
|
||||||
int.tryParse(value.toString()) ??
|
|
||||||
(value is double ? value.toInt() : null)))
|
|
||||||
.cast<String, int>()
|
|
||||||
: {},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@ -118,8 +106,37 @@ class Post {
|
|||||||
'is_draft': isDraft,
|
'is_draft': isDraft,
|
||||||
'author_id': authorId,
|
'author_id': authorId,
|
||||||
'author': author.toJson(),
|
'author': author.toJson(),
|
||||||
'reply_count': replyCount,
|
'metric': metric?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostMetric {
|
||||||
|
int reactionCount;
|
||||||
|
Map<String, int> reactionList;
|
||||||
|
int replyCount;
|
||||||
|
|
||||||
|
PostMetric({
|
||||||
|
required this.reactionCount,
|
||||||
|
required this.reactionList,
|
||||||
|
required this.replyCount,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PostMetric.fromJson(Map<String, dynamic> json) => PostMetric(
|
||||||
|
reactionCount: json['reaction_count'],
|
||||||
|
replyCount: json['reply_count'],
|
||||||
|
reactionList: json['reaction_list'] != null
|
||||||
|
? json['reaction_list']
|
||||||
|
.map((key, value) => MapEntry(
|
||||||
|
key,
|
||||||
|
int.tryParse(value.toString()) ??
|
||||||
|
(value is double ? value.toInt() : null)))
|
||||||
|
.cast<String, int>()
|
||||||
|
: {},
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
'reaction_count': reactionCount,
|
'reaction_count': reactionCount,
|
||||||
|
'reply_count': replyCount,
|
||||||
'reaction_list': reactionList,
|
'reaction_list': reactionList,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class StatusProvider extends GetConnect {
|
|||||||
void onInit() {
|
void onInit() {
|
||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
|
|
||||||
httpClient.baseUrl = ServiceFinder.services['passport'];
|
httpClient.baseUrl = ServiceFinder.buildUrl('auth', null);
|
||||||
httpClient.addAuthenticator(auth.requestAuthenticator);
|
httpClient.addAuthenticator(auth.requestAuthenticator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,13 +35,13 @@ class StatusProvider extends GetConnect {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
return await client.get('/api/users/me/status');
|
return await client.get('/users/me/status');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> getSomeoneStatus(String name) =>
|
Future<Response> getSomeoneStatus(String name) =>
|
||||||
get('/api/users/$name/status');
|
get('/users/$name/status');
|
||||||
|
|
||||||
Future<Response> setStatus(
|
Future<Response> setStatus(
|
||||||
String type,
|
String type,
|
||||||
@ -55,7 +55,7 @@ class StatusProvider extends GetConnect {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final payload = {
|
final payload = {
|
||||||
'type': type,
|
'type': type,
|
||||||
@ -68,9 +68,9 @@ class StatusProvider extends GetConnect {
|
|||||||
|
|
||||||
Response resp;
|
Response resp;
|
||||||
if (!isUpdate) {
|
if (!isUpdate) {
|
||||||
resp = await client.post('/api/users/me/status', payload);
|
resp = await client.post('/users/me/status', payload);
|
||||||
} else {
|
} else {
|
||||||
resp = await client.put('/api/users/me/status', payload);
|
resp = await client.put('/users/me/status', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
@ -84,9 +84,9 @@ class StatusProvider extends GetConnect {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.delete('/api/users/me/status');
|
final resp = await client.delete('/users/me/status');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:get/get_connect/http/src/request/request.dart';
|
import 'package:get/get_connect/http/src/request/request.dart';
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
import 'package:solian/controllers/chat_events_controller.dart';
|
import 'package:solian/controllers/chat_events_controller.dart';
|
||||||
import 'package:solian/providers/account.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/chat.dart';
|
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
|
|
||||||
class TokenSet {
|
class TokenSet {
|
||||||
@ -48,7 +47,7 @@ class RiskyAuthenticateException implements Exception {
|
|||||||
|
|
||||||
class AuthProvider extends GetConnect {
|
class AuthProvider extends GetConnect {
|
||||||
final tokenEndpoint =
|
final tokenEndpoint =
|
||||||
Uri.parse('${ServiceFinder.services['passport']}/api/auth/token');
|
Uri.parse(ServiceFinder.buildUrl('auth', '/auth/token'));
|
||||||
|
|
||||||
static const clientId = 'solian';
|
static const clientId = 'solian';
|
||||||
static const clientSecret = '_F4%q2Eea3';
|
static const clientSecret = '_F4%q2Eea3';
|
||||||
@ -60,7 +59,7 @@ class AuthProvider extends GetConnect {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
httpClient.baseUrl = ServiceFinder.services['passport'];
|
httpClient.baseUrl = ServiceFinder.buildUrl('auth', null);
|
||||||
loadCredentials();
|
loadCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ class AuthProvider extends GetConnect {
|
|||||||
try {
|
try {
|
||||||
credentialsRefreshMutex.acquire();
|
credentialsRefreshMutex.acquire();
|
||||||
if (!credentials!.isExpired) return;
|
if (!credentials!.isExpired) return;
|
||||||
final resp = await post('/api/auth/token', {
|
final resp = await post('/auth/token', {
|
||||||
'refresh_token': credentials!.refreshToken,
|
'refresh_token': credentials!.refreshToken,
|
||||||
'grant_type': 'refresh_token',
|
'grant_type': 'refresh_token',
|
||||||
});
|
});
|
||||||
@ -111,7 +110,7 @@ class AuthProvider extends GetConnect {
|
|||||||
sendUserAgent: true,
|
sendUserAgent: true,
|
||||||
);
|
);
|
||||||
client.httpClient.addAuthenticator(requestAuthenticator);
|
client.httpClient.addAuthenticator(requestAuthenticator);
|
||||||
client.httpClient.baseUrl = ServiceFinder.services[service];
|
client.httpClient.baseUrl = ServiceFinder.buildUrl(service, null);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
@ -140,10 +139,10 @@ class AuthProvider extends GetConnect {
|
|||||||
) async {
|
) async {
|
||||||
_cachedUserProfileResponse = null;
|
_cachedUserProfileResponse = null;
|
||||||
|
|
||||||
final client = ServiceFinder.configureClient('passport');
|
final client = ServiceFinder.configureClient('auth');
|
||||||
|
|
||||||
// Create ticket
|
// Create ticket
|
||||||
final resp = await client.post('/api/auth', {
|
final resp = await client.post('/auth', {
|
||||||
'username': username,
|
'username': username,
|
||||||
'password': password,
|
'password': password,
|
||||||
});
|
});
|
||||||
@ -154,7 +153,7 @@ class AuthProvider extends GetConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Assign token
|
// Assign token
|
||||||
final tokenResp = await post('/api/auth/token', {
|
final tokenResp = await post('/auth/token', {
|
||||||
'code': resp.body['ticket']['grant_token'],
|
'code': resp.body['ticket']['grant_token'],
|
||||||
'grant_type': 'grant_token',
|
'grant_type': 'grant_token',
|
||||||
});
|
});
|
||||||
@ -173,9 +172,8 @@ class AuthProvider extends GetConnect {
|
|||||||
value: jsonEncode(credentials!.toJson()),
|
value: jsonEncode(credentials!.toJson()),
|
||||||
);
|
);
|
||||||
|
|
||||||
Get.find<AccountProvider>().connect();
|
Get.find<WebSocketProvider>().connect();
|
||||||
Get.find<AccountProvider>().notifyPrefetch();
|
Get.find<WebSocketProvider>().notifyPrefetch();
|
||||||
Get.find<ChatProvider>().connect();
|
|
||||||
|
|
||||||
return credentials!;
|
return credentials!;
|
||||||
}
|
}
|
||||||
@ -183,10 +181,9 @@ class AuthProvider extends GetConnect {
|
|||||||
void signout() {
|
void signout() {
|
||||||
_cachedUserProfileResponse = null;
|
_cachedUserProfileResponse = null;
|
||||||
|
|
||||||
Get.find<ChatProvider>().disconnect();
|
Get.find<WebSocketProvider>().disconnect();
|
||||||
Get.find<AccountProvider>().disconnect();
|
Get.find<WebSocketProvider>().notifications.clear();
|
||||||
Get.find<AccountProvider>().notifications.clear();
|
Get.find<WebSocketProvider>().notificationUnread.value = 0;
|
||||||
Get.find<AccountProvider>().notificationUnread.value = 0;
|
|
||||||
|
|
||||||
final chatHistory = ChatEventController();
|
final chatHistory = ChatEventController();
|
||||||
chatHistory.initialize().then((_) async {
|
chatHistory.initialize().then((_) async {
|
||||||
@ -207,9 +204,9 @@ class AuthProvider extends GetConnect {
|
|||||||
return _cachedUserProfileResponse!;
|
return _cachedUserProfileResponse!;
|
||||||
}
|
}
|
||||||
|
|
||||||
final client = configureClient('passport');
|
final client = configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.get('/api/users/me');
|
final resp = await client.get('/users/me');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:solian/models/packet.dart';
|
|
||||||
import 'package:solian/providers/auth.dart';
|
|
||||||
import 'package:solian/services.dart';
|
|
||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
|
||||||
|
|
||||||
class ChatProvider extends GetxController {
|
|
||||||
RxBool isConnected = false.obs;
|
|
||||||
RxBool isConnecting = false.obs;
|
|
||||||
|
|
||||||
WebSocketChannel? websocket;
|
|
||||||
|
|
||||||
StreamController<NetworkPackage> stream = StreamController.broadcast();
|
|
||||||
|
|
||||||
void connect({noRetry = false}) async {
|
|
||||||
if (isConnected.value) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
final AuthProvider auth = Get.find();
|
|
||||||
await auth.ensureCredentials();
|
|
||||||
|
|
||||||
if (auth.credentials == null) await auth.loadCredentials();
|
|
||||||
|
|
||||||
final uri = Uri.parse(
|
|
||||||
'${ServiceFinder.services['messaging']}/api/ws?tk=${auth.credentials!.accessToken}'
|
|
||||||
.replaceFirst('http', 'ws'),
|
|
||||||
);
|
|
||||||
|
|
||||||
isConnecting.value = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
websocket = WebSocketChannel.connect(uri);
|
|
||||||
await websocket?.ready;
|
|
||||||
} catch (e) {
|
|
||||||
if (!noRetry) {
|
|
||||||
await auth.refreshCredentials();
|
|
||||||
return connect(noRetry: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listen();
|
|
||||||
|
|
||||||
isConnected.value = true;
|
|
||||||
isConnecting.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnect() {
|
|
||||||
websocket?.sink.close(WebSocketStatus.normalClosure);
|
|
||||||
websocket = null;
|
|
||||||
isConnected.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void listen() {
|
|
||||||
websocket?.stream.listen(
|
|
||||||
(event) {
|
|
||||||
final packet = NetworkPackage.fromJson(jsonDecode(event));
|
|
||||||
stream.sink.add(packet);
|
|
||||||
},
|
|
||||||
onDone: () {
|
|
||||||
isConnected.value = false;
|
|
||||||
Future.delayed(const Duration(seconds: 1), () => connect());
|
|
||||||
},
|
|
||||||
onError: (err) {
|
|
||||||
isConnected.value = false;
|
|
||||||
Future.delayed(const Duration(seconds: 3), () => connect());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -58,7 +58,7 @@ class AttachmentProvider extends GetConnect {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
httpClient.baseUrl = ServiceFinder.services['paperclip'];
|
httpClient.baseUrl = ServiceFinder.buildUrl('files', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<int, Response> _cachedResponses = {};
|
final Map<int, Response> _cachedResponses = {};
|
||||||
@ -68,7 +68,7 @@ class AttachmentProvider extends GetConnect {
|
|||||||
return _cachedResponses[id]!;
|
return _cachedResponses[id]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
final resp = await get('/api/attachments/$id/meta');
|
final resp = await get('/attachments/$id/meta');
|
||||||
_cachedResponses[id] = resp;
|
_cachedResponses[id] = resp;
|
||||||
|
|
||||||
return resp;
|
return resp;
|
||||||
@ -81,7 +81,7 @@ class AttachmentProvider extends GetConnect {
|
|||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient(
|
final client = auth.configureClient(
|
||||||
'paperclip',
|
'files',
|
||||||
timeout: const Duration(minutes: 3),
|
timeout: const Duration(minutes: 3),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ class AttachmentProvider extends GetConnect {
|
|||||||
if (ratio != null) 'ratio': ratio,
|
if (ratio != null) 'ratio': ratio,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
final resp = await client.post('/api/attachments', payload);
|
final resp = await client.post('/attachments', payload);
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -126,9 +126,9 @@ class AttachmentProvider extends GetConnect {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('paperclip');
|
final client = auth.configureClient('files');
|
||||||
|
|
||||||
var resp = await client.put('/api/attachments/$id', {
|
var resp = await client.put('/attachments/$id', {
|
||||||
'metadata': {
|
'metadata': {
|
||||||
if (ratio != null) 'ratio': ratio,
|
if (ratio != null) 'ratio': ratio,
|
||||||
},
|
},
|
||||||
@ -148,9 +148,9 @@ class AttachmentProvider extends GetConnect {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('paperclip');
|
final client = auth.configureClient('files');
|
||||||
|
|
||||||
var resp = await client.delete('/api/attachments/$id');
|
var resp = await client.delete('/attachments/$id');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ class ChatCallProvider extends GetxController {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.post(
|
final resp = await client.post(
|
||||||
'/api/channels/global/${channel.value!.alias}/calls/ongoing/token',
|
'/channels/global/${channel.value!.alias}/calls/ongoing/token',
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
|
@ -33,7 +33,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get('/api/channels/$realm/$alias');
|
final resp = await client.get('/channels/$realm/$alias');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get('/api/channels/$realm/$alias/me');
|
final resp = await client.get('/channels/$realm/$alias/me');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get('/api/channels/$realm/$alias/calls/ongoing');
|
final resp = await client.get('/channels/$realm/$alias/calls/ongoing');
|
||||||
if (resp.statusCode == 404) {
|
if (resp.statusCode == 404) {
|
||||||
return null;
|
return null;
|
||||||
} else if (resp.statusCode != 200) {
|
} else if (resp.statusCode != 200) {
|
||||||
@ -79,7 +79,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get('/api/channels/$scope');
|
final resp = await client.get('/channels/$scope');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get('/api/channels/$realm/me/available');
|
final resp = await client.get('/channels/$realm/me/available');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.post('/api/channels/$scope', payload);
|
final resp = await client.post('/channels/$scope', payload);
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ class ChannelProvider extends GetxController {
|
|||||||
final prof = await auth.getProfile();
|
final prof = await auth.getProfile();
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.post('/api/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),
|
||||||
'name': 'DM',
|
'name': 'DM',
|
||||||
'description':
|
'description':
|
||||||
@ -153,7 +153,7 @@ class ChannelProvider extends GetxController {
|
|||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.put('/api/channels/$scope/$id', payload);
|
final resp = await client.put('/channels/$scope/$id', payload);
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import 'package:solian/services.dart';
|
|||||||
class FeedProvider extends GetConnect {
|
class FeedProvider extends GetConnect {
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
httpClient.baseUrl = ServiceFinder.services['interactive'];
|
httpClient.baseUrl = ServiceFinder.buildUrl('interactive', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> listFeed(int page,
|
Future<Response> listFeed(int page,
|
||||||
@ -17,7 +17,7 @@ class FeedProvider extends GetConnect {
|
|||||||
if (category != null) 'category=$category',
|
if (category != null) 'category=$category',
|
||||||
if (realm != null) 'realmId=$realm',
|
if (realm != null) 'realmId=$realm',
|
||||||
];
|
];
|
||||||
final resp = await get('/api/feed?${queries.join('&')}');
|
final resp = await get('/feed?${queries.join('&')}');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ class FeedProvider extends GetConnect {
|
|||||||
'offset=$page',
|
'offset=$page',
|
||||||
];
|
];
|
||||||
final client = auth.configureClient('interactive');
|
final client = auth.configureClient('interactive');
|
||||||
final resp = await client.get('/api/drafts?${queries.join('&')}');
|
final resp = await client.get('/drafts?${queries.join('&')}');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ class FeedProvider extends GetConnect {
|
|||||||
'offset=$page',
|
'offset=$page',
|
||||||
if (realm != null) 'realmId=$realm',
|
if (realm != null) 'realmId=$realm',
|
||||||
];
|
];
|
||||||
final resp = await get('/api/posts?${queries.join('&')}');
|
final resp = await get('/posts?${queries.join('&')}');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ class FeedProvider extends GetConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> listPostReplies(String alias, int page) async {
|
Future<Response> listPostReplies(String alias, int page) async {
|
||||||
final resp = await get('/api/posts/$alias/replies?take=${10}&offset=$page');
|
final resp = await get('/posts/$alias/replies?take=${10}&offset=$page');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ class FeedProvider extends GetConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> getPost(String alias) async {
|
Future<Response> getPost(String alias) async {
|
||||||
final resp = await get('/api/posts/$alias');
|
final resp = await get('/posts/$alias');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ class FeedProvider extends GetConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> getArticle(String alias) async {
|
Future<Response> getArticle(String alias) async {
|
||||||
final resp = await get('/api/articles/$alias');
|
final resp = await get('/articles/$alias');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.body);
|
throw Exception(resp.body);
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ class RealmProvider extends GetxController {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.get('/api/realms/$alias');
|
final resp = await client.get('/realms/$alias');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -20,9 +20,9 @@ class RealmProvider extends GetxController {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.get('/api/realms/me/available');
|
final resp = await client.get('/realms/me/available');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,17 @@ class FriendProvider extends GetConnect {
|
|||||||
void onInit() {
|
void onInit() {
|
||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
|
|
||||||
httpClient.baseUrl = ServiceFinder.services['passport'];
|
httpClient.baseUrl = ServiceFinder.buildUrl('auth', null);
|
||||||
httpClient.addAuthenticator(auth.requestAuthenticator);
|
httpClient.addAuthenticator(auth.requestAuthenticator);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> listFriendship() => get('/api/users/me/friends');
|
Future<Response> listFriendship() => get('/users/me/friends');
|
||||||
|
|
||||||
Future<Response> listFriendshipWithStatus(int status) =>
|
Future<Response> listFriendshipWithStatus(int status) =>
|
||||||
get('/api/users/me/friends?status=$status');
|
get('/users/me/friends?status=$status');
|
||||||
|
|
||||||
Future<Response> createFriendship(String username) async {
|
Future<Response> createFriendship(String username) async {
|
||||||
final resp = await post('/api/users/me/friends?related=$username', {});
|
final resp = await post('/users/me/friends?related=$username', {});
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
throw Exception(resp.bodyString);
|
throw Exception(resp.bodyString);
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ class FriendProvider extends GetConnect {
|
|||||||
final prof = await auth.getProfile();
|
final prof = await auth.getProfile();
|
||||||
final otherside = relationship.getOtherside(prof.body['id']);
|
final otherside = relationship.getOtherside(prof.body['id']);
|
||||||
|
|
||||||
final resp = await put('/api/users/me/friends/${otherside.id}', {
|
final resp = await put('/users/me/friends/${otherside.id}', {
|
||||||
'status': status,
|
'status': status,
|
||||||
});
|
});
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
|
@ -23,7 +23,7 @@ Future<Event?> getRemoteEvent(int id, Channel channel, String scope) async {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get(
|
final resp = await client.get(
|
||||||
'/api/channels/$scope/${channel.alias}/events/$id',
|
'/channels/$scope/${channel.alias}/events/$id',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (resp.statusCode == 404) {
|
if (resp.statusCode == 404) {
|
||||||
@ -53,7 +53,7 @@ Future<(List<Event>, int)?> getRemoteEvents(
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.get(
|
final resp = await client.get(
|
||||||
'/api/channels/$scope/${channel.alias}/events?take=$take&offset=$offset',
|
'/channels/$scope/${channel.alias}/events?take=$take&offset=$offset',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
|
@ -16,7 +16,7 @@ import 'package:solian/services.dart';
|
|||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
|
||||||
class AccountProvider extends GetxController {
|
class WebSocketProvider extends GetxController {
|
||||||
final FlutterLocalNotificationsPlugin localNotify =
|
final FlutterLocalNotificationsPlugin localNotify =
|
||||||
FlutterLocalNotificationsPlugin();
|
FlutterLocalNotificationsPlugin();
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ class AccountProvider extends GetxController {
|
|||||||
|
|
||||||
WebSocketChannel? websocket;
|
WebSocketChannel? websocket;
|
||||||
|
|
||||||
|
StreamController<NetworkPackage> stream = StreamController.broadcast();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
onInit() {
|
onInit() {
|
||||||
FirebaseMessaging.instance
|
FirebaseMessaging.instance
|
||||||
@ -58,10 +60,10 @@ class AccountProvider extends GetxController {
|
|||||||
|
|
||||||
if (auth.credentials == null) await auth.loadCredentials();
|
if (auth.credentials == null) await auth.loadCredentials();
|
||||||
|
|
||||||
final uri = Uri.parse(
|
final uri = Uri.parse(ServiceFinder.buildUrl(
|
||||||
'${ServiceFinder.services['passport']}/api/ws?tk=${auth.credentials!.accessToken}'
|
'dealer',
|
||||||
.replaceFirst('http', 'ws'),
|
'/api/ws?tk=${auth.credentials!.accessToken}',
|
||||||
);
|
).replaceFirst('http', 'ws'));
|
||||||
|
|
||||||
isConnecting.value = true;
|
isConnecting.value = true;
|
||||||
|
|
||||||
@ -91,6 +93,8 @@ class AccountProvider extends GetxController {
|
|||||||
websocket?.stream.listen(
|
websocket?.stream.listen(
|
||||||
(event) {
|
(event) {
|
||||||
final packet = NetworkPackage.fromJson(jsonDecode(event));
|
final packet = NetworkPackage.fromJson(jsonDecode(event));
|
||||||
|
stream.sink.add(packet);
|
||||||
|
|
||||||
switch (packet.method) {
|
switch (packet.method) {
|
||||||
case 'notifications.new':
|
case 'notifications.new':
|
||||||
final notification = Notification.fromJson(packet.payload!);
|
final notification = Notification.fromJson(packet.payload!);
|
||||||
@ -166,9 +170,9 @@ class AccountProvider extends GetxController {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) return;
|
if (!await auth.isAuthorized) return;
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.get('/api/notifications?skip=0&take=100');
|
final resp = await client.get('/notifications?skip=0&take=100');
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
final result = PaginationResult.fromJson(resp.body);
|
final result = PaginationResult.fromJson(resp.body);
|
||||||
final data = result.data?.map((x) => Notification.fromJson(x)).toList();
|
final data = result.data?.map((x) => Notification.fromJson(x)).toList();
|
||||||
@ -199,9 +203,9 @@ class AccountProvider extends GetxController {
|
|||||||
token = await FirebaseMessaging.instance.getToken();
|
token = await FirebaseMessaging.instance.getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.post('/api/notifications/subscribe', {
|
final resp = await client.post('/notifications/subscribe', {
|
||||||
'provider': provider,
|
'provider': provider,
|
||||||
'device_token': token,
|
'device_token': token,
|
||||||
'device_id': deviceUuid,
|
'device_id': deviceUuid,
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/providers/account.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/models/notification.dart' as notify;
|
import 'package:solian/models/notification.dart' as notify;
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
@ -23,7 +23,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final AccountProvider provider = Get.find();
|
final WebSocketProvider provider = Get.find();
|
||||||
|
|
||||||
List<int> markList = List.empty(growable: true);
|
List<int> markList = List.empty(growable: true);
|
||||||
for (final element in provider.notifications) {
|
for (final element in provider.notifications) {
|
||||||
@ -32,8 +32,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (markList.isNotEmpty) {
|
if (markList.isNotEmpty) {
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
await client.put('/api/notifications/batch/read', {'messages': markList});
|
await client.put('/notifications/batch/read', {'messages': markList});
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.notifications.clear();
|
provider.notifications.clear();
|
||||||
@ -45,7 +45,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
if (!await auth.isAuthorized) return;
|
if (!await auth.isAuthorized) return;
|
||||||
|
|
||||||
final AccountProvider provider = Get.find();
|
final WebSocketProvider provider = Get.find();
|
||||||
|
|
||||||
if (element.id <= 0) {
|
if (element.id <= 0) {
|
||||||
provider.notifications.removeAt(index);
|
provider.notifications.removeAt(index);
|
||||||
@ -54,9 +54,9 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
await client.put('/api/notifications/${element.id}/read', {});
|
await client.put('/notifications/${element.id}/read', {});
|
||||||
|
|
||||||
provider.notifications.removeAt(index);
|
provider.notifications.removeAt(index);
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final AccountProvider provider = Get.find();
|
final WebSocketProvider provider = Get.find();
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: MediaQuery.of(context).size.height * 0.85,
|
height: MediaQuery.of(context).size.height * 0.85,
|
||||||
@ -175,7 +175,7 @@ class NotificationButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final AccountProvider provider = Get.find();
|
final WebSocketProvider provider = Get.find();
|
||||||
|
|
||||||
final button = IconButton(
|
final button = IconButton(
|
||||||
icon: const Icon(Icons.notifications),
|
icon: const Icon(Icons.notifications),
|
||||||
|
@ -100,10 +100,10 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.put(
|
final resp = await client.put(
|
||||||
'/api/users/me/$position',
|
'/users/me/$position',
|
||||||
{'attachment': attachResp.body['id']},
|
{'attachment': attachResp.body['id']},
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
@ -122,11 +122,11 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
_birthday?.toIso8601String();
|
_birthday?.toIso8601String();
|
||||||
final resp = await client.put(
|
final resp = await client.put(
|
||||||
'/api/users/me',
|
'/users/me',
|
||||||
{
|
{
|
||||||
'nick': _nicknameController.value.text,
|
'nick': _nicknameController.value.text,
|
||||||
'description': _descriptionController.value.text,
|
'description': _descriptionController.value.text,
|
||||||
@ -189,7 +189,7 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
|
|||||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
child: _banner != null
|
child: _banner != null
|
||||||
? Image.network(
|
? Image.network(
|
||||||
'${ServiceFinder.services['paperclip']}/api/attachments/$_banner',
|
ServiceFinder.buildUrl('files', '/attachments/$_banner'),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
loadingBuilder: (BuildContext context, Widget child,
|
loadingBuilder: (BuildContext context, Widget child,
|
||||||
ImageChunkEvent? loadingProgress) {
|
ImageChunkEvent? loadingProgress) {
|
||||||
|
@ -84,9 +84,9 @@ class _ArticlePublishScreenState extends State<ArticlePublishScreen> {
|
|||||||
|
|
||||||
Response resp;
|
Response resp;
|
||||||
if (widget.edit != null) {
|
if (widget.edit != null) {
|
||||||
resp = await client.put('/api/articles/${widget.edit!.id}', payload);
|
resp = await client.put('/articles/${widget.edit!.id}', payload);
|
||||||
} else {
|
} else {
|
||||||
resp = await client.post('/api/articles', payload);
|
resp = await client.post('/articles', payload);
|
||||||
}
|
}
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString);
|
context.showErrorDialog(resp.bodyString);
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:protocol_handler/protocol_handler.dart';
|
import 'package:protocol_handler/protocol_handler.dart';
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
import 'package:solian/providers/account.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@ -30,15 +30,15 @@ class _SignInPopupState extends State<SignInPopup> with ProtocolListener {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = ServiceFinder.configureClient('passport');
|
final client = ServiceFinder.configureClient('auth');
|
||||||
final lookupResp = await client.get('/api/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);
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final resp = await client.post('/api/users/me/password-reset', {
|
final resp = await client.post('/users/me/password-reset', {
|
||||||
'user_id': lookupResp.body['id'],
|
'user_id': lookupResp.body['id'],
|
||||||
});
|
});
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
@ -75,7 +75,7 @@ class _SignInPopupState extends State<SignInPopup> with ProtocolListener {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
const redirect = 'solink://auth?status=done';
|
const redirect = 'solink://auth?status=done';
|
||||||
launchUrlString(
|
launchUrlString(
|
||||||
'${ServiceFinder.services['passport']}/mfa?redirect_uri=$redirect&ticketId=${e.ticketId}',
|
ServiceFinder.buildUrl('passport', '/mfa?redirect_uri=$redirect&ticketId=${e.ticketId}'),
|
||||||
mode: LaunchMode.inAppWebView,
|
mode: LaunchMode.inAppWebView,
|
||||||
);
|
);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@ -93,7 +93,7 @@ class _SignInPopupState extends State<SignInPopup> with ProtocolListener {
|
|||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Get.find<AccountProvider>().registerPushNotifications();
|
Get.find<WebSocketProvider>().registerPushNotifications();
|
||||||
|
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ class _SignUpPopupState extends State<SignUpPopup> {
|
|||||||
nickname.isEmpty ||
|
nickname.isEmpty ||
|
||||||
password.isEmpty) return;
|
password.isEmpty) return;
|
||||||
|
|
||||||
final client = ServiceFinder.configureClient('passport');
|
final client = ServiceFinder.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.post('/api/users', {
|
final resp = await client.post('/users', {
|
||||||
'name': username,
|
'name': username,
|
||||||
'nick': nickname,
|
'nick': nickname,
|
||||||
'email': email,
|
'email': email,
|
||||||
|
@ -11,9 +11,9 @@ import 'package:solian/models/channel.dart';
|
|||||||
import 'package:solian/models/event.dart';
|
import 'package:solian/models/event.dart';
|
||||||
import 'package:solian/models/packet.dart';
|
import 'package:solian/models/packet.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/providers/chat.dart';
|
|
||||||
import 'package:solian/providers/content/call.dart';
|
import 'package:solian/providers/content/call.dart';
|
||||||
import 'package:solian/providers/content/channel.dart';
|
import 'package:solian/providers/content/channel.dart';
|
||||||
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/screens/channel/channel_detail.dart';
|
import 'package:solian/screens/channel/channel_detail.dart';
|
||||||
import 'package:solian/theme.dart';
|
import 'package:solian/theme.dart';
|
||||||
@ -107,7 +107,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void listenMessages() {
|
void listenMessages() {
|
||||||
final ChatProvider provider = Get.find();
|
final WebSocketProvider provider = Get.find();
|
||||||
_subscription = provider.stream.stream.listen((event) {
|
_subscription = provider.stream.stream.listen((event) {
|
||||||
switch (event.method) {
|
switch (event.method) {
|
||||||
case 'events.new':
|
case 'events.new':
|
||||||
|
@ -82,7 +82,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.put(
|
final resp = await client.put(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/members/me', {
|
'/channels/${widget.realm}/${widget.channel.alias}/members/me', {
|
||||||
'nick': null,
|
'nick': null,
|
||||||
'notify_level': _notifyLevel,
|
'notify_level': _notifyLevel,
|
||||||
});
|
});
|
||||||
|
@ -90,9 +90,9 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
|
|||||||
|
|
||||||
Response resp;
|
Response resp;
|
||||||
if (widget.edit != null) {
|
if (widget.edit != null) {
|
||||||
resp = await client.put('/api/posts/${widget.edit!.id}', payload);
|
resp = await client.put('/posts/${widget.edit!.id}', payload);
|
||||||
} else {
|
} else {
|
||||||
resp = await client.post('/api/posts', payload);
|
resp = await client.post('/posts', payload);
|
||||||
}
|
}
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString);
|
context.showErrorDialog(resp.bodyString);
|
||||||
|
@ -43,7 +43,7 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final payload = {
|
final payload = {
|
||||||
'alias': _aliasController.value.text.toLowerCase(),
|
'alias': _aliasController.value.text.toLowerCase(),
|
||||||
@ -55,9 +55,9 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> {
|
|||||||
|
|
||||||
Response resp;
|
Response resp;
|
||||||
if (widget.edit != null) {
|
if (widget.edit != null) {
|
||||||
resp = await client.put('/api/realms/${widget.edit!.id}', payload);
|
resp = await client.put('/realms/${widget.edit!.id}', payload);
|
||||||
} else {
|
} else {
|
||||||
resp = await client.post('/api/realms', payload);
|
resp = await client.post('/realms', payload);
|
||||||
}
|
}
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString);
|
context.showErrorDialog(resp.bodyString);
|
||||||
|
@ -3,23 +3,29 @@ import 'package:get/get.dart';
|
|||||||
abstract class ServiceFinder {
|
abstract class ServiceFinder {
|
||||||
static const bool devFlag = false;
|
static const bool devFlag = false;
|
||||||
|
|
||||||
static Map<String, String> services = {
|
static const String dealerUrl =
|
||||||
'paperclip':
|
devFlag ? 'http://localhost:8442' : 'https://api.sn.solsynth.dev';
|
||||||
devFlag ? 'http://localhost:8443' : 'https://usercontent.solsynth.dev',
|
static const String passportUrl =
|
||||||
'passport': devFlag ? 'http://localhost:8444' : 'https://id.solsynth.dev',
|
devFlag ? 'http://localhost:8444' : 'https://id.solsynth.dev';
|
||||||
'interactive':
|
|
||||||
devFlag ? 'http://localhost:8445' : 'https://co.solsynth.dev',
|
|
||||||
'messaging': devFlag ? 'http://localhost:8447' : 'https://im.solsynth.dev',
|
|
||||||
};
|
|
||||||
|
|
||||||
static GetConnect configureClient(String service,
|
static String buildUrl(String serviceName, String? append) {
|
||||||
|
append ??= '';
|
||||||
|
if (serviceName == 'dealer') {
|
||||||
|
return '$dealerUrl$append';
|
||||||
|
} else if (serviceName == 'passport') {
|
||||||
|
return '$passportUrl$append';
|
||||||
|
}
|
||||||
|
return '$dealerUrl/srv/$serviceName$append';
|
||||||
|
}
|
||||||
|
|
||||||
|
static GetConnect configureClient(String serviceName,
|
||||||
{timeout = const Duration(seconds: 5)}) {
|
{timeout = const Duration(seconds: 5)}) {
|
||||||
final client = GetConnect(
|
final client = GetConnect(
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
userAgent: 'Solian/1.1',
|
userAgent: 'Solian/1.1',
|
||||||
sendUserAgent: true,
|
sendUserAgent: true,
|
||||||
);
|
);
|
||||||
client.httpClient.baseUrl = ServiceFinder.services[service];
|
client.httpClient.baseUrl = buildUrl(serviceName, null);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ class AccountAvatar extends StatelessWidget {
|
|||||||
if (content is String) {
|
if (content is String) {
|
||||||
direct = content.startsWith('http');
|
direct = content.startsWith('http');
|
||||||
if (!isEmpty) isEmpty = content.isEmpty;
|
if (!isEmpty) isEmpty = content.isEmpty;
|
||||||
if (!isEmpty) isEmpty = content.endsWith('/api/attachments/0');
|
if (!isEmpty) isEmpty = content.endsWith('/attachments/0');
|
||||||
}
|
}
|
||||||
|
|
||||||
final url = direct
|
final url = direct
|
||||||
? content
|
? content
|
||||||
: '${ServiceFinder.services['paperclip']}/api/attachments/$content';
|
: ServiceFinder.buildUrl('files', '/attachments/$content');
|
||||||
|
|
||||||
return CircleAvatar(
|
return CircleAvatar(
|
||||||
key: Key('a$content'),
|
key: Key('a$content'),
|
||||||
@ -68,12 +68,12 @@ class AccountProfileImage extends StatelessWidget {
|
|||||||
if (content is String) {
|
if (content is String) {
|
||||||
direct = content.startsWith('http');
|
direct = content.startsWith('http');
|
||||||
if (!isEmpty) isEmpty = content.isEmpty;
|
if (!isEmpty) isEmpty = content.isEmpty;
|
||||||
if (!isEmpty) isEmpty = content.endsWith('/api/attachments/0');
|
if (!isEmpty) isEmpty = content.endsWith('/attachments/0');
|
||||||
}
|
}
|
||||||
|
|
||||||
final url = direct
|
final url = direct
|
||||||
? content
|
? content
|
||||||
: '${ServiceFinder.services['paperclip']}/api/attachments/$content';
|
: ServiceFinder.buildUrl('files', '/attachments/$content');
|
||||||
|
|
||||||
if (PlatformInfo.canCacheImage) {
|
if (PlatformInfo.canCacheImage) {
|
||||||
return CachedNetworkImage(
|
return CachedNetworkImage(
|
||||||
|
@ -24,9 +24,9 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
|
|||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = GetConnect();
|
final client = GetConnect();
|
||||||
client.httpClient.baseUrl = ServiceFinder.services['passport'];
|
client.httpClient.baseUrl = ServiceFinder.buildUrl('auth', null);
|
||||||
|
|
||||||
final resp = await client.get('/api/users/${widget.account.name}');
|
final resp = await client.get('/users/${widget.account.name}');
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
_userinfo = Account.fromJson(resp.body);
|
_userinfo = Account.fromJson(resp.body);
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
|
@ -123,7 +123,7 @@ class _ArticleDeletionDialogState extends State<ArticleDeletionDialog> {
|
|||||||
final client = auth.configureClient('interactive');
|
final client = auth.configureClient('interactive');
|
||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
final resp = await client.delete('/api/articles/${widget.item.id}');
|
final resp = await client.delete('/articles/${widget.item.id}');
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
|
@ -192,8 +192,8 @@ class _ArticleItemState extends State<ArticleItem> {
|
|||||||
item: widget.item,
|
item: widget.item,
|
||||||
onReact: (symbol, changes) {
|
onReact: (symbol, changes) {
|
||||||
setState(() {
|
setState(() {
|
||||||
item.reactionList[symbol] =
|
item.metric!.reactionList[symbol] =
|
||||||
(item.reactionList[symbol] ?? 0) + changes;
|
(item.metric!.reactionList[symbol] ?? 0) + changes;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
).paddingOnly(
|
).paddingOnly(
|
||||||
|
@ -30,7 +30,7 @@ class _ArticleQuickActionState extends State<ArticleQuickAction> {
|
|||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => PostReactionPopup(
|
builder: (context) => PostReactionPopup(
|
||||||
reactionList: widget.item.reactionList,
|
reactionList: widget.item.metric!.reactionList,
|
||||||
onReact: (key, value) {
|
onReact: (key, value) {
|
||||||
doWidgetReact(key, value.attitude);
|
doWidgetReact(key, value.attitude);
|
||||||
},
|
},
|
||||||
@ -50,7 +50,7 @@ class _ArticleQuickActionState extends State<ArticleQuickAction> {
|
|||||||
|
|
||||||
setState(() => _isSubmitting = true);
|
setState(() => _isSubmitting = true);
|
||||||
|
|
||||||
final resp = await client.post('/api/articles/${widget.item.alias}/react', {
|
final resp = await client.post('/articles/${widget.item.alias}/react', {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'attitude': attitude,
|
'attitude': attitude,
|
||||||
});
|
});
|
||||||
@ -71,7 +71,7 @@ class _ArticleQuickActionState extends State<ArticleQuickAction> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
if (!widget.isReactable && widget.item.reactionList.isEmpty) {
|
if (!widget.isReactable && widget.item.metric!.reactionList.isEmpty) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
widget.onReact('thumb_up', 0);
|
widget.onReact('thumb_up', 0);
|
||||||
});
|
});
|
||||||
@ -94,7 +94,7 @@ class _ArticleQuickActionState extends State<ArticleQuickAction> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
...widget.item.reactionList.entries.map((x) {
|
...widget.item.metric!.reactionList.entries.map((x) {
|
||||||
final info = reactions[x.key];
|
final info = reactions[x.key];
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(right: 8),
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
@ -82,7 +82,8 @@ class _AttachmentItemState extends State<AttachmentItem> {
|
|||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
launchUrlString(
|
launchUrlString(
|
||||||
'${ServiceFinder.services['paperclip']}/api/attachments/${widget.item.id}',
|
ServiceFinder.buildUrl(
|
||||||
|
'files', '/attachments/${widget.item.id}'),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -117,7 +118,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Hero(
|
return Hero(
|
||||||
tag: Key('a${item.uuid}p${parentId}'),
|
tag: Key('a${item.uuid}p$parentId'),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
@ -125,7 +126,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
|||||||
CachedNetworkImage(
|
CachedNetworkImage(
|
||||||
fit: fit,
|
fit: fit,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'${ServiceFinder.services['paperclip']}/api/attachments/${item.id}',
|
ServiceFinder.buildUrl('files', '/attachments/${item.id}'),
|
||||||
progressIndicatorBuilder: (context, url, downloadProgress) =>
|
progressIndicatorBuilder: (context, url, downloadProgress) =>
|
||||||
Center(
|
Center(
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
@ -135,7 +136,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
else
|
else
|
||||||
Image.network(
|
Image.network(
|
||||||
'${ServiceFinder.services['paperclip']}/api/attachments/${item.id}',
|
ServiceFinder.buildUrl('files', '/attachments/${item.id}'),
|
||||||
fit: fit,
|
fit: fit,
|
||||||
loadingBuilder: (BuildContext context, Widget child,
|
loadingBuilder: (BuildContext context, Widget child,
|
||||||
ImageChunkEvent? loadingProgress) {
|
ImageChunkEvent? loadingProgress) {
|
||||||
@ -205,7 +206,7 @@ class _AttachmentItemVideoState extends State<_AttachmentItemVideo> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
_player.open(
|
_player.open(
|
||||||
Media(
|
Media(
|
||||||
'${ServiceFinder.services['paperclip']}/api/attachments/${widget.item.id}',
|
ServiceFinder.buildUrl('files', '/attachments/${widget.item.id}'),
|
||||||
),
|
),
|
||||||
play: false,
|
play: false,
|
||||||
);
|
);
|
||||||
|
@ -32,7 +32,7 @@ class _ChannelDeletionDialogState extends State<ChannelDeletionDialog> {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client
|
final resp = await client
|
||||||
.delete('/api/channels/${widget.realm}/${widget.channel.id}');
|
.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)) {
|
||||||
@ -51,7 +51,7 @@ class _ChannelDeletionDialogState extends State<ChannelDeletionDialog> {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.delete(
|
final resp = await client.delete(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/members/me',
|
'/channels/${widget.realm}/${widget.channel.alias}/members/me',
|
||||||
);
|
);
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString);
|
context.showErrorDialog(resp.bodyString);
|
||||||
|
@ -118,11 +118,7 @@ class _ChannelListWidgetState extends State<ChannelListWidget> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
minTileHeight: item.realmId == null
|
minTileHeight: widget.isDense ? 48 : null,
|
||||||
? 48
|
|
||||||
: widget.isDense
|
|
||||||
? 24
|
|
||||||
: null,
|
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
item.realmId == null ? Colors.indigo : Colors.transparent,
|
item.realmId == null ? Colors.indigo : Colors.transparent,
|
||||||
|
@ -43,7 +43,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
|
|||||||
final client = ServiceFinder.configureClient('messaging');
|
final client = ServiceFinder.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client
|
final resp = await client
|
||||||
.get('/api/channels/${widget.realm}/${widget.channel.alias}/members');
|
.get('/channels/${widget.realm}/${widget.channel.alias}/members');
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_members = resp.body
|
_members = resp.body
|
||||||
@ -79,7 +79,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.post(
|
final resp = await client.post(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/members',
|
'/channels/${widget.realm}/${widget.channel.alias}/members',
|
||||||
{'target': username},
|
{'target': username},
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
@ -100,7 +100,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
|
|||||||
final client = auth.configureClient('messaging');
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
final resp = await client.request(
|
final resp = await client.request(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/members',
|
'/channels/${widget.realm}/${widget.channel.alias}/members',
|
||||||
'delete',
|
'delete',
|
||||||
body: {'target': item.account.name},
|
body: {'target': item.account.name},
|
||||||
);
|
);
|
||||||
|
@ -41,7 +41,7 @@ class _ChatCallButtonState extends State<ChatCallButton> {
|
|||||||
? widget.realm?.alias
|
? widget.realm?.alias
|
||||||
: 'global';
|
: 'global';
|
||||||
final resp = await client.post(
|
final resp = await client.post(
|
||||||
'/api/channels/$scope/${widget.channel.alias}/calls',
|
'/channels/$scope/${widget.channel.alias}/calls',
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
@ -65,7 +65,7 @@ class _ChatCallButtonState extends State<ChatCallButton> {
|
|||||||
? widget.realm?.alias
|
? widget.realm?.alias
|
||||||
: 'global';
|
: 'global';
|
||||||
final resp = await client
|
final resp = await client
|
||||||
.delete('/api/channels/$scope/${widget.channel.alias}/calls/ongoing');
|
.delete('/channels/$scope/${widget.channel.alias}/calls/ongoing');
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
if (widget.onEnded != null) widget.onEnded!();
|
if (widget.onEnded != null) widget.onEnded!();
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +38,7 @@ class _ChatEventDeletionDialogState extends State<ChatEventDeletionDialog> {
|
|||||||
? widget.realm?.alias
|
? widget.realm?.alias
|
||||||
: 'global';
|
: 'global';
|
||||||
final resp = await client.delete(
|
final resp = await client.delete(
|
||||||
'/api/channels/$scope/${widget.channel.alias}/messages/${widget.item.id}',
|
'/channels/$scope/${widget.channel.alias}/messages/${widget.item.id}',
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
Navigator.pop(context, resp.body);
|
Navigator.pop(context, resp.body);
|
||||||
|
@ -114,12 +114,12 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
|
|||||||
Response resp;
|
Response resp;
|
||||||
if (_editTo != null) {
|
if (_editTo != null) {
|
||||||
resp = await client.put(
|
resp = await client.put(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/messages/${_editTo!.id}',
|
'/channels/${widget.realm}/${widget.channel.alias}/messages/${_editTo!.id}',
|
||||||
payload,
|
payload,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
resp = await client.post(
|
resp = await client.post(
|
||||||
'/api/channels/${widget.realm}/${widget.channel.alias}/messages',
|
'/channels/${widget.realm}/${widget.channel.alias}/messages',
|
||||||
payload,
|
payload,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/providers/account.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/providers/chat.dart';
|
|
||||||
|
|
||||||
class BackgroundStateWidget extends StatelessWidget {
|
class BackgroundStateWidget extends StatelessWidget {
|
||||||
const BackgroundStateWidget({super.key});
|
const BackgroundStateWidget({super.key});
|
||||||
@ -11,14 +10,11 @@ class BackgroundStateWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final AuthProvider auth = Get.find();
|
final AuthProvider auth = Get.find();
|
||||||
final AccountProvider account = Get.find();
|
final WebSocketProvider ws = Get.find();
|
||||||
final ChatProvider chat = Get.find();
|
|
||||||
|
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final disconnected =
|
final disconnected = ws.isConnected.isFalse;
|
||||||
chat.isConnected.isFalse || account.isConnected.isFalse;
|
final connecting = ws.isConnecting.isTrue;
|
||||||
final connecting =
|
|
||||||
chat.isConnecting.isTrue || account.isConnecting.isTrue;
|
|
||||||
|
|
||||||
return Row(children: [
|
return Row(children: [
|
||||||
if (disconnected && !connecting)
|
if (disconnected && !connecting)
|
||||||
@ -30,10 +26,8 @@ class BackgroundStateWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
return IconButton(
|
return IconButton(
|
||||||
tooltip: [
|
tooltip: [
|
||||||
if (account.isConnected.isFalse)
|
if (ws.isConnected.isFalse)
|
||||||
'Lost Connection with Passport Server...',
|
'Lost Connection with Solar Network...',
|
||||||
if (chat.isConnected.isFalse)
|
|
||||||
'Lost Connection with Messaging Server...',
|
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
icon: const Icon(Icons.wifi_off)
|
icon: const Icon(Icons.wifi_off)
|
||||||
.animate(onPlay: (c) => c.repeat())
|
.animate(onPlay: (c) => c.repeat())
|
||||||
@ -41,8 +35,7 @@ class BackgroundStateWidget extends StatelessWidget {
|
|||||||
.then()
|
.then()
|
||||||
.fadeOut(duration: 800.ms),
|
.fadeOut(duration: 800.ms),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (account.isConnected.isFalse) account.connect();
|
if (ws.isConnected.isFalse) ws.connect();
|
||||||
if (chat.isConnected.isFalse) chat.connect();
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -56,10 +49,8 @@ class BackgroundStateWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
return IconButton(
|
return IconButton(
|
||||||
tooltip: [
|
tooltip: [
|
||||||
if (account.isConnecting.isTrue)
|
if (ws.isConnecting.isTrue)
|
||||||
'Waiting Passport Server Response...',
|
'Waiting Solar Network Connection...',
|
||||||
if (chat.isConnecting.isTrue)
|
|
||||||
'Waiting Messaging Server Response...',
|
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
icon: const Icon(Icons.sync)
|
icon: const Icon(Icons.sync)
|
||||||
.animate(onPlay: (c) => c.repeat())
|
.animate(onPlay: (c) => c.repeat())
|
||||||
|
@ -158,7 +158,7 @@ class _PostDeletionDialogState extends State<PostDeletionDialog> {
|
|||||||
final client = auth.configureClient('interactive');
|
final client = auth.configureClient('interactive');
|
||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
final resp = await client.delete('/api/posts/${widget.item.id}');
|
final resp = await client.delete('/posts/${widget.item.id}');
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
|
@ -304,8 +304,8 @@ class _PostItemState extends State<PostItem> {
|
|||||||
item: widget.item,
|
item: widget.item,
|
||||||
onReact: (symbol, changes) {
|
onReact: (symbol, changes) {
|
||||||
setState(() {
|
setState(() {
|
||||||
item.reactionList[symbol] =
|
item.metric!.reactionList[symbol] =
|
||||||
(item.reactionList[symbol] ?? 0) + changes;
|
(item.metric!.reactionList[symbol] ?? 0) + changes;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
).paddingOnly(
|
).paddingOnly(
|
||||||
|
@ -33,7 +33,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
|
|||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => PostReactionPopup(
|
builder: (context) => PostReactionPopup(
|
||||||
reactionList: widget.item.reactionList,
|
reactionList: widget.item.metric!.reactionList,
|
||||||
onReact: (key, value) {
|
onReact: (key, value) {
|
||||||
doWidgetReact(key, value.attitude);
|
doWidgetReact(key, value.attitude);
|
||||||
},
|
},
|
||||||
@ -53,7 +53,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
|
|||||||
|
|
||||||
setState(() => _isSubmitting = true);
|
setState(() => _isSubmitting = true);
|
||||||
|
|
||||||
final resp = await client.post('/api/posts/${widget.item.alias}/react', {
|
final resp = await client.post('/posts/${widget.item.alias}/react', {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'attitude': attitude,
|
'attitude': attitude,
|
||||||
});
|
});
|
||||||
@ -74,7 +74,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
if (!widget.isReactable && widget.item.reactionList.isEmpty) {
|
if (!widget.isReactable && widget.item.metric!.reactionList.isEmpty) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
widget.onReact('thumb_up', 0);
|
widget.onReact('thumb_up', 0);
|
||||||
});
|
});
|
||||||
@ -95,7 +95,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
|
|||||||
if (widget.isReactable && widget.isShowReply)
|
if (widget.isReactable && widget.isShowReply)
|
||||||
ActionChip(
|
ActionChip(
|
||||||
avatar: const Icon(Icons.comment),
|
avatar: const Icon(Icons.comment),
|
||||||
label: Text(widget.item.replyCount.toString()),
|
label: Text(widget.item.metric!.replyCount.toString()),
|
||||||
visualDensity: density,
|
visualDensity: density,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
@ -119,7 +119,7 @@ class _PostQuickActionState extends State<PostQuickAction> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
...widget.item.reactionList.entries.map((x) {
|
...widget.item.metric!.reactionList.entries.map((x) {
|
||||||
final info = reactions[x.key];
|
final info = reactions[x.key];
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(right: 8),
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
@ -27,9 +27,9 @@ class _RealmDeletionDialogState extends State<RealmDeletionDialog> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.delete('/api/realms/${widget.realm.id}');
|
final resp = await client.delete('/realms/${widget.realm.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)) {
|
||||||
@ -45,10 +45,10 @@ class _RealmDeletionDialogState extends State<RealmDeletionDialog> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp =
|
final resp =
|
||||||
await client.delete('/api/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)) {
|
||||||
|
@ -38,9 +38,9 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
|
|||||||
void getMembers() async {
|
void getMembers() async {
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = ServiceFinder.configureClient('passport');
|
final client = ServiceFinder.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.get('/api/realms/${widget.realm.alias}/members');
|
final resp = await client.get('/realms/${widget.realm.alias}/members');
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_members = resp.body
|
_members = resp.body
|
||||||
@ -73,10 +73,10 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.post(
|
final resp = await client.post(
|
||||||
'/api/realms/${widget.realm.alias}/members',
|
'/realms/${widget.realm.alias}/members',
|
||||||
{'target': username},
|
{'target': username},
|
||||||
);
|
);
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
@ -94,10 +94,10 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = auth.configureClient('passport');
|
final client = auth.configureClient('auth');
|
||||||
|
|
||||||
final resp = await client.request(
|
final resp = await client.request(
|
||||||
'/api/realms/${widget.realm.alias}/members',
|
'/realms/${widget.realm.alias}/members',
|
||||||
'delete',
|
'delete',
|
||||||
body: {'target': item.account.name},
|
body: {'target': item.account.name},
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user