Complete the realm system

This commit is contained in:
LittleSheep 2024-05-06 23:30:30 +08:00
parent 22c2a80650
commit ae4d9cf81a
6 changed files with 100 additions and 12 deletions

View File

@ -28,6 +28,7 @@
"birthday": "Birthday", "birthday": "Birthday",
"password": "Password", "password": "Password",
"next": "Next", "next": "Next",
"join": "Join",
"edit": "Edit", "edit": "Edit",
"apply": "Apply", "apply": "Apply",
"delete": "Delete", "delete": "Delete",
@ -95,6 +96,9 @@
"chatDetail": "Chat Details", "chatDetail": "Chat Details",
"chatMember": "Member", "chatMember": "Member",
"chatNotifySetting": "Notify Settings", "chatNotifySetting": "Notify Settings",
"chatChannelUnavailable": "Channel Unavailable",
"chatChannelUnavailableCaptionWithRealm": "You didn't join the channel, but looks like you able to join to, would you want to have a try?",
"chatChannelUnavailableCaption": "You didn't join the channel, so you cannot access the information of this channel.",
"chatChannelUsage": "Channel", "chatChannelUsage": "Channel",
"chatChannelUsageCaption": "Channel is place to talk with people, one or a lot.", "chatChannelUsageCaption": "Channel is place to talk with people, one or a lot.",
"chatChannelOrganize": "Organize a channel", "chatChannelOrganize": "Organize a channel",

View File

@ -2,6 +2,7 @@
"appName": "Solar Network", "appName": "Solar Network",
"explore": "探索", "explore": "探索",
"chat": "聊天", "chat": "聊天",
"realm": "领域",
"account": "账号", "account": "账号",
"riskDetection": "风险监测", "riskDetection": "风险监测",
"signIn": "登录", "signIn": "登录",
@ -27,6 +28,7 @@
"birthday": "生日", "birthday": "生日",
"password": "密码", "password": "密码",
"next": "下一步", "next": "下一步",
"join": "加入",
"edit": "编辑", "edit": "编辑",
"delete": "删除", "delete": "删除",
"action": "操作", "action": "操作",
@ -74,10 +76,27 @@
"postEditNotify": "你正在修改一个已经发布了的帖子。", "postEditNotify": "你正在修改一个已经发布了的帖子。",
"reactionAdded": "你的反应已被添加。", "reactionAdded": "你的反应已被添加。",
"reactionRemoved": "你的反应已被移除。", "reactionRemoved": "你的反应已被移除。",
"realmNew": "新领域",
"realmNewCreate": "创建新领域",
"realmNewJoin": "加入现有领域",
"realmUsage": "领域",
"realmUsageCaption": "领域是一个地方给你来组织帖子、文章、聊天频道的,好好利用领域打造一个绝妙的专属于你的社区吧!",
"realmEstablish": "部署领域",
"realmEditNotify": "你正在修改一个现有领域……",
"realmAliasLabel": "领域别名",
"realmNameLabel": "领域名称",
"realmDescriptionLabel": "领域简介",
"realmPublicLabel": "公共领域",
"realmCommunityLabel": "社区领域(任何人均可加入)",
"realmMember": "成员",
"realmManage": "领域管理",
"chatNew": "新聊天", "chatNew": "新聊天",
"chatDetail": "聊天详情", "chatDetail": "聊天详情",
"chatMember": "成员", "chatMember": "成员",
"chatNotifySetting": "通知设定", "chatNotifySetting": "通知设定",
"chatChannelUnavailable": "频道不可用",
"chatChannelUnavailableCaptionWithRealm": "你没加入该频道,但是看起来你能加入本频道,你想加入吗?",
"chatChannelUnavailableCaption": "你没加入该频道,所以你无法读取本频道的信息。",
"chatNewCreate": "新建频道", "chatNewCreate": "新建频道",
"chatNewJoin": "加入已有频道", "chatNewJoin": "加入已有频道",
"chatChannelUsage": "频道", "chatChannelUsage": "频道",

View File

@ -15,6 +15,8 @@ class Channel {
int accountId; int accountId;
int? realmId; int? realmId;
bool isAvailable = false;
Channel({ Channel({
required this.id, required this.id,
required this.createdAt, required this.createdAt,

View File

@ -44,14 +44,13 @@ class ChatProvider extends ChangeNotifier {
return channel; return channel;
} }
Future<Channel> fetchChannel(String alias, String realm) async { Future<Channel> fetchChannel(AuthProvider auth, String alias, String realm) async {
final Client client = Client(); var uri = getRequestUri('messaging', '/api/channels/$realm/$alias/availability');
var res = await auth.client!.get(uri);
var uri = getRequestUri('messaging', '/api/channels/$realm/$alias'); if (res.statusCode == 200 || res.statusCode == 403) {
var res = await client.get(uri);
if (res.statusCode == 200) {
final result = jsonDecode(utf8.decode(res.bodyBytes)); final result = jsonDecode(utf8.decode(res.bodyBytes));
focusChannel = Channel.fromJson(result); focusChannel = Channel.fromJson(result);
focusChannel?.isAvailable = res.statusCode == 200;
notifyListeners(); notifyListeners();
return focusChannel!; return focusChannel!;
} else { } else {

View File

@ -16,6 +16,7 @@ import 'package:solian/widgets/chat/chat_maintainer.dart';
import 'package:solian/widgets/chat/message.dart'; import 'package:solian/widgets/chat/message.dart';
import 'package:solian/widgets/chat/message_action.dart'; import 'package:solian/widgets/chat/message_action.dart';
import 'package:solian/widgets/chat/message_editor.dart'; import 'package:solian/widgets/chat/message_editor.dart';
import 'package:solian/widgets/exts.dart';
import 'package:solian/widgets/scaffold.dart'; import 'package:solian/widgets/scaffold.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -27,6 +28,7 @@ class ChatScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final auth = context.read<AuthProvider>();
final chat = context.watch<ChatProvider>(); final chat = context.watch<ChatProvider>();
return IndentScaffold( return IndentScaffold(
@ -39,12 +41,12 @@ class ChatScreen extends StatelessWidget {
call: chat.ongoingCall, call: chat.ongoingCall,
channel: chat.focusChannel!, channel: chat.focusChannel!,
realm: realm, realm: realm,
onUpdate: () => chat.fetchChannel(chat.focusChannel!.alias, realm), onUpdate: () => chat.fetchChannel(auth, chat.focusChannel!.alias, realm),
), ),
ChannelManageAction( ChannelManageAction(
channel: chat.focusChannel!, channel: chat.focusChannel!,
realm: realm, realm: realm,
onUpdate: () => chat.fetchChannel(chat.focusChannel!.alias, realm), onUpdate: () => chat.fetchChannel(auth, chat.focusChannel!.alias, realm),
), ),
] ]
: [], : [],
@ -96,11 +98,34 @@ class _ChatWidgetState extends State<ChatWidget> {
final nextPageKey = pageKey + items.length; final nextPageKey = pageKey + items.length;
_pagingController.appendPage(items, nextPageKey); _pagingController.appendPage(items, nextPageKey);
} }
} else if (res.statusCode == 403) {
_pagingController.appendLastPage([]);
} else { } else {
_pagingController.error = utf8.decode(res.bodyBytes); _pagingController.error = utf8.decode(res.bodyBytes);
} }
} }
Future<void> joinChannel() async {
final auth = context.read<AuthProvider>();
if (!await auth.isAuthorized()) return;
var uri = getRequestUri(
'messaging',
'/api/channels/${widget.realm}/${widget.alias}/members/me',
);
var res = await auth.client!.post(uri);
if (res.statusCode == 200) {
setState(() {});
_pagingController.refresh();
} else {
var message = utf8.decode(res.bodyBytes);
context.showErrorDialog(message).then((_) {
SolianRouter.router.pop();
});
}
}
bool getMessageMergeable(Message? a, Message? b) { bool getMessageMergeable(Message? a, Message? b) {
if (a?.replyTo != null) return false; if (a?.replyTo != null) return false;
if (a == null || b == null) return false; if (a == null || b == null) return false;
@ -145,15 +170,55 @@ class _ChatWidgetState extends State<ChatWidget> {
); );
} }
void showUnavailableDialog() {
final content = widget.realm == 'global'
? AppLocalizations.of(context)!.chatChannelUnavailableCaption
: AppLocalizations.of(context)!.chatChannelUnavailableCaptionWithRealm;
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Text(AppLocalizations.of(context)!.chatChannelUnavailable),
content: Text(content),
actions: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context)!.cancel),
onPressed: () {
Navigator.of(context).pop();
SolianRouter.router.pop();
},
),
...(widget.realm != 'global'
? [
TextButton(
child: Text(AppLocalizations.of(context)!.join),
onPressed: () {
Navigator.of(context).pop();
joinChannel();
},
),
]
: [])
],
),
);
}
@override @override
void initState() { void initState() {
_pagingController.addPageRequestListener((pageKey) => fetchMessages(pageKey, context)); _pagingController.addPageRequestListener((pageKey) => fetchMessages(pageKey, context));
super.initState(); super.initState();
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () async {
final auth = context.read<AuthProvider>();
_chat.fetchOngoingCall(widget.alias, widget.realm); _chat.fetchOngoingCall(widget.alias, widget.realm);
_chat.fetchChannel(widget.alias, widget.realm); _chat.fetchChannel(auth, widget.alias, widget.realm).then((result) {
if (result.isAvailable == false) {
showUnavailableDialog();
}
});
}); });
} }

View File

@ -29,8 +29,7 @@ class _ItemDeletionDialogState extends State<ItemDeletionDialog> {
final auth = context.read<AuthProvider>(); final auth = context.read<AuthProvider>();
if (!await auth.isAuthorized()) return; if (!await auth.isAuthorized()) return;
final uri = final uri = getRequestUri('interactive', '/api/p/${widget.item.modelType}s/${widget.item.id}');
getRequestUri('interactive', '/api/p/moments/${widget.item.id}');
setState(() => _isSubmitting = true); setState(() => _isSubmitting = true);
final res = await auth.client!.delete(uri); final res = await auth.client!.delete(uri);