Realm basis

This commit is contained in:
2024-05-05 23:01:08 +08:00
parent cf0d473a40
commit 384d861d56
26 changed files with 851 additions and 147 deletions

View File

@ -13,9 +13,16 @@ import 'package:solian/widgets/exts.dart';
class ChannelCallAction extends StatefulWidget {
final Call? call;
final Channel channel;
final String realm;
final Function onUpdate;
const ChannelCallAction({super.key, this.call, required this.channel, required this.onUpdate});
const ChannelCallAction({
super.key,
this.call,
required this.channel,
required this.onUpdate,
this.realm = 'global',
});
@override
State<ChannelCallAction> createState() => _ChannelCallActionState();
@ -33,7 +40,7 @@ class _ChannelCallActionState extends State<ChannelCallAction> {
return;
}
var uri = getRequestUri('messaging', '/api/channels/global/${widget.channel.alias}/calls');
var uri = getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel.alias}/calls');
var res = await auth.client!.post(uri);
if (res.statusCode != 200) {
@ -54,7 +61,7 @@ class _ChannelCallActionState extends State<ChannelCallAction> {
return;
}
var uri = getRequestUri('messaging', '/api/channels/global/${widget.channel.alias}/calls/ongoing');
var uri = getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel.alias}/calls/ongoing');
var res = await auth.client!.delete(uri);
if (res.statusCode != 200) {
@ -90,17 +97,26 @@ class _ChannelCallActionState extends State<ChannelCallAction> {
class ChannelManageAction extends StatelessWidget {
final Channel channel;
final Function onUpdate;
final String realm;
const ChannelManageAction({super.key, required this.channel, required this.onUpdate});
const ChannelManageAction({
super.key,
required this.channel,
required this.onUpdate,
this.realm = 'global',
});
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: () async {
final result = await SolianRouter.router.pushNamed(
'chat.channel.manage',
realm == 'global' ? 'chat.channel.manage' : 'realms.chat.channel.manage',
extra: channel,
pathParameters: {'channel': channel.alias},
pathParameters: {
'channel': channel.alias,
...(realm == 'global' ? {} : {'realm': realm}),
},
);
switch (result) {
case 'disposed':

View File

@ -10,10 +10,15 @@ import 'package:solian/widgets/exts.dart';
class ChannelDeletion extends StatefulWidget {
final Channel channel;
final String realm;
final bool isOwned;
const ChannelDeletion(
{super.key, required this.channel, required this.isOwned});
const ChannelDeletion({
super.key,
required this.channel,
required this.realm,
required this.isOwned,
});
@override
State<ChannelDeletion> createState() => _ChannelDeletionState();
@ -32,7 +37,7 @@ class _ChannelDeletionState extends State<ChannelDeletion> {
}
var res = await auth.client!.delete(
getRequestUri('messaging', '/api/channels/global/${widget.channel.id}'),
getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel.id}'),
);
if (res.statusCode != 200) {
var message = utf8.decode(res.bodyBytes);
@ -53,8 +58,8 @@ class _ChannelDeletionState extends State<ChannelDeletion> {
return;
}
var res = await auth.client!.post(
getRequestUri('messaging', '/api/channels/global/${widget.channel.alias}/leave'),
var res = await auth.client!.delete(
getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel.alias}/me'),
);
if (res.statusCode != 200) {
var message = utf8.decode(res.bodyBytes);

View File

@ -4,8 +4,9 @@ import 'package:solian/router.dart';
class ChatNewAction extends StatelessWidget {
final Function onUpdate;
final String? realm;
const ChatNewAction({super.key, required this.onUpdate});
const ChatNewAction({super.key, required this.onUpdate, this.realm});
@override
Widget build(BuildContext context) {
@ -29,7 +30,10 @@ class ChatNewAction extends StatelessWidget {
leading: const Icon(Icons.add),
title: Text(AppLocalizations.of(context)!.chatNewCreate),
onTap: () {
SolianRouter.router.pushNamed('chat.channel.editor').then((did) {
SolianRouter.router.pushNamed(
'chat.channel.editor',
queryParameters: {'realm': realm},
).then((did) {
if (did == true) {
onUpdate();
if (Navigator.canPop(context)) {

View File

@ -14,11 +14,19 @@ import 'package:badges/badges.dart' as badge;
class ChatMessageEditor extends StatefulWidget {
final String channel;
final String realm;
final Message? editing;
final Message? replying;
final Function? onReset;
const ChatMessageEditor({super.key, required this.channel, this.editing, this.replying, this.onReset});
const ChatMessageEditor({
super.key,
required this.channel,
this.realm = 'global',
this.editing,
this.replying,
this.onReset,
});
@override
State<ChatMessageEditor> createState() => _ChatMessageEditorState();
@ -53,8 +61,8 @@ class _ChatMessageEditorState extends State<ChatMessageEditor> {
if (!await auth.isAuthorized()) return;
final uri = widget.editing == null
? getRequestUri('messaging', '/api/channels/global/${widget.channel}/messages')
: getRequestUri('messaging', '/api/channels/global/${widget.channel}/messages/${widget.editing!.id}');
? getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel}/messages')
: getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel}/messages/${widget.editing!.id}');
final req = Request(widget.editing == null ? 'POST' : 'PUT', uri);
req.headers['Content-Type'] = 'application/json';

View File

@ -42,6 +42,13 @@ class _SolianNavigationDrawerState extends State<SolianNavigationDrawer> {
),
'explore',
),
(
NavigationDrawerDestination(
icon: const Icon(Icons.supervised_user_circle),
label: Text(AppLocalizations.of(context)!.realm),
),
'realms',
),
(
NavigationDrawerDestination(
icon: const Icon(Icons.send),

View File

@ -1,4 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:solian/utils/platform.dart';
class AttachmentScreen extends StatelessWidget {
final String url;
@ -17,7 +19,7 @@ class AttachmentScreen extends StatelessWidget {
maxScale: 16,
panEnabled: true,
scaleEnabled: true,
child: Image.network(url, fit: BoxFit.contain),
child: PlatformInfo.canCacheImage ? CachedNetworkImage(imageUrl: url, fit: BoxFit.contain) : Image.network(url),
),
);

View File

@ -1,9 +1,10 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:solian/models/post.dart';
import 'package:markdown/markdown.dart' as markdown;
import 'package:solian/utils/platform.dart';
import 'package:solian/utils/service_url.dart';
import 'package:solian/widgets/posts/content/attachment.dart';
import 'package:url_launcher/url_launcher_string.dart';
class ArticleContent extends StatelessWidget {
@ -61,10 +62,9 @@ class ArticleContent extends StatelessWidget {
uri = url;
}
return AttachmentItem(
type: 1,
url: uri.toString(),
);
return PlatformInfo.canCacheImage
? CachedNetworkImage(imageUrl: uri.toString())
: Image.network(uri.toString());
},
),
],

View File

@ -1,6 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/models/post.dart';
import 'package:solian/router.dart';

View File

@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:solian/router.dart';
class RealmNewAction extends StatelessWidget {
final Function onUpdate;
const RealmNewAction({super.key, required this.onUpdate});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 320,
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(left: 20, top: 20, bottom: 8),
child: Text(
AppLocalizations.of(context)!.realmNew,
style: Theme.of(context).textTheme.headlineSmall,
),
),
Expanded(
child: ListView(
children: [
ListTile(
leading: const Icon(Icons.add),
title: Text(AppLocalizations.of(context)!.realmNewCreate),
onTap: () {
SolianRouter.router.pushNamed('realms.editor').then((did) {
if (did == true) {
onUpdate();
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
}
});
},
),
ListTile(
leading: const Icon(Icons.travel_explore),
title: Text(AppLocalizations.of(context)!.realmNewJoin),
),
],
),
),
],
),
);
}
}