🐛 Bug fixes
This commit is contained in:
parent
30184d08b1
commit
408fd0f35e
@ -671,5 +671,8 @@
|
|||||||
"attachmentBillingDiscount": "Free space",
|
"attachmentBillingDiscount": "Free space",
|
||||||
"attachmentBillingRatio": "Usage",
|
"attachmentBillingRatio": "Usage",
|
||||||
"attachmentBillingHint": "Sliding Window Pricing®\nFees will only apply if the size of the file uploaded within 24 hours exceeds the free space.",
|
"attachmentBillingHint": "Sliding Window Pricing®\nFees will only apply if the size of the file uploaded within 24 hours exceeds the free space.",
|
||||||
"postThumbnail": "Post Thumbnail"
|
"postThumbnail": "Post Thumbnail",
|
||||||
|
"accountRealms": "Realms",
|
||||||
|
"postInGlobal": "Global",
|
||||||
|
"postInGlobalDescription": "Do not link this post with any realm."
|
||||||
}
|
}
|
||||||
|
@ -669,5 +669,8 @@
|
|||||||
"attachmentBillingUploaded": "已占用的字节数",
|
"attachmentBillingUploaded": "已占用的字节数",
|
||||||
"attachmentBillingDiscount": "免费的字节数",
|
"attachmentBillingDiscount": "免费的字节数",
|
||||||
"attachmentBillingHint": "滑动窗口计价®\n在24小时内上传的文件大小超出免费空间才会适用扣费。",
|
"attachmentBillingHint": "滑动窗口计价®\n在24小时内上传的文件大小超出免费空间才会适用扣费。",
|
||||||
"postThumbnail": "帖子缩略图"
|
"postThumbnail": "帖子缩略图",
|
||||||
|
"accountRealms": "领域",
|
||||||
|
"postInGlobal": "全站",
|
||||||
|
"postInGlobalDescription": "不关联此帖子与任何领域。"
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import 'package:surface/providers/sn_network.dart';
|
|||||||
import 'package:surface/types/attachment.dart';
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/types/poll.dart';
|
import 'package:surface/types/poll.dart';
|
||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
|
import 'package:surface/types/realm.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/universal_image.dart';
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
import 'package:video_compress/video_compress.dart';
|
import 'package:video_compress/video_compress.dart';
|
||||||
@ -197,6 +198,7 @@ class PostWriteController extends ChangeNotifier {
|
|||||||
bool isLoading = false, isBusy = false;
|
bool isLoading = false, isBusy = false;
|
||||||
double? progress;
|
double? progress;
|
||||||
|
|
||||||
|
SnRealm? realm;
|
||||||
SnPublisher? publisher;
|
SnPublisher? publisher;
|
||||||
SnPost? editingPost, repostingPost, replyingPost;
|
SnPost? editingPost, repostingPost, replyingPost;
|
||||||
|
|
||||||
@ -625,6 +627,11 @@ class PostWriteController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setRealm(SnRealm? value) {
|
||||||
|
realm = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void setProgress(double? value) {
|
void setProgress(double? value) {
|
||||||
progress = value;
|
progress = value;
|
||||||
_temporaryPlanSave();
|
_temporaryPlanSave();
|
||||||
|
@ -31,6 +31,7 @@ import 'package:surface/providers/post.dart';
|
|||||||
import 'package:surface/providers/relationship.dart';
|
import 'package:surface/providers/relationship.dart';
|
||||||
import 'package:surface/providers/sn_attachment.dart';
|
import 'package:surface/providers/sn_attachment.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/providers/sn_realm.dart';
|
||||||
import 'package:surface/providers/sn_sticker.dart';
|
import 'package:surface/providers/sn_sticker.dart';
|
||||||
import 'package:surface/providers/special_day.dart';
|
import 'package:surface/providers/special_day.dart';
|
||||||
import 'package:surface/providers/theme.dart';
|
import 'package:surface/providers/theme.dart';
|
||||||
@ -159,6 +160,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
Provider(create: (ctx) => SnRelationshipProvider(ctx)),
|
Provider(create: (ctx) => SnRelationshipProvider(ctx)),
|
||||||
Provider(create: (ctx) => SnLinkPreviewProvider(ctx)),
|
Provider(create: (ctx) => SnLinkPreviewProvider(ctx)),
|
||||||
Provider(create: (ctx) => SnStickerProvider(ctx)),
|
Provider(create: (ctx) => SnStickerProvider(ctx)),
|
||||||
|
Provider(create: (ctx) => SnRealmProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),
|
||||||
|
26
lib/providers/sn_realm.dart
Normal file
26
lib/providers/sn_realm.dart
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/types/realm.dart';
|
||||||
|
|
||||||
|
class SnRealmProvider {
|
||||||
|
late final SnNetworkProvider _sn;
|
||||||
|
|
||||||
|
SnRealmProvider(BuildContext context) {
|
||||||
|
_sn = context.read<SnNetworkProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<SnRealm>> listAvailableRealms() async {
|
||||||
|
final resp = await _sn.client.get('/cgi/id/realms/me/available');
|
||||||
|
final out = List<SnRealm>.from(
|
||||||
|
resp.data?.map((e) => SnRealm.fromJson(e)) ?? [],
|
||||||
|
);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SnRealm> getRealm(String alias) async {
|
||||||
|
final resp = await _sn.client.get('/cgi/id/realms/$alias');
|
||||||
|
final out = SnRealm.fromJson(resp.data);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
@ -104,7 +104,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
|
|||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
await sn.client.delete(
|
await sn.client.delete(
|
||||||
'/cgi/im/channels/${_channel!.realm?.alias ?? 'global'}/${_channel!.alias}/members/me',
|
'/cgi/im/channels/${_channel!.realm?.alias ?? 'global'}/${_channel!.alias}/me',
|
||||||
);
|
);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pop(context, false);
|
Navigator.pop(context, false);
|
||||||
|
@ -20,6 +20,7 @@ import 'package:surface/providers/sn_attachment.dart';
|
|||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/types/attachment.dart';
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
|
import 'package:surface/types/realm.dart';
|
||||||
import 'package:surface/widgets/account/account_image.dart';
|
import 'package:surface/widgets/account/account_image.dart';
|
||||||
import 'package:surface/widgets/attachment/attachment_input.dart';
|
import 'package:surface/widgets/attachment/attachment_input.dart';
|
||||||
import 'package:surface/widgets/attachment/attachment_item.dart';
|
import 'package:surface/widgets/attachment/attachment_item.dart';
|
||||||
@ -35,6 +36,8 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:surface/widgets/post/post_poll_editor.dart';
|
import 'package:surface/widgets/post/post_poll_editor.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
import '../../providers/sn_realm.dart';
|
||||||
|
|
||||||
class PostEditorExtra {
|
class PostEditorExtra {
|
||||||
final String? text;
|
final String? text;
|
||||||
final String? title;
|
final String? title;
|
||||||
@ -79,6 +82,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
bool get _isLoading => _isFetching || _writeController.isLoading;
|
bool get _isLoading => _isFetching || _writeController.isLoading;
|
||||||
|
|
||||||
List<SnPublisher>? _publishers;
|
List<SnPublisher>? _publishers;
|
||||||
|
List<SnRealm>? _realms;
|
||||||
|
|
||||||
Future<void> _fetchPublishers() async {
|
Future<void> _fetchPublishers() async {
|
||||||
setState(() => _isFetching = true);
|
setState(() => _isFetching = true);
|
||||||
@ -101,6 +105,16 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _fetchRealms() async {
|
||||||
|
final rels = context.read<SnRealmProvider>();
|
||||||
|
try {
|
||||||
|
_realms = await rels.listAvailableRealms();
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _updateMeta() {
|
void _updateMeta() {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@ -144,6 +158,19 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showRealmPopup() {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => _PostRealmPopup(
|
||||||
|
controller: _writeController,
|
||||||
|
realms: _realms,
|
||||||
|
onUpdate: () {
|
||||||
|
_fetchRealms();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _showPollEditorDialog() async {
|
void _showPollEditorDialog() async {
|
||||||
final poll = await showDialog<dynamic>(
|
final poll = await showDialog<dynamic>(
|
||||||
context: context,
|
context: context,
|
||||||
@ -194,6 +221,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
} else {
|
} else {
|
||||||
_writeController.setMode(widget.mode);
|
_writeController.setMode(widget.mode);
|
||||||
}
|
}
|
||||||
|
_fetchRealms();
|
||||||
_fetchPublishers();
|
_fetchPublishers();
|
||||||
_writeController.fetchRelatedPost(
|
_writeController.fetchRelatedPost(
|
||||||
context,
|
context,
|
||||||
@ -335,6 +363,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
|
|||||||
'stories' => _PostStoryEditor(
|
'stories' => _PostStoryEditor(
|
||||||
controller: _writeController,
|
controller: _writeController,
|
||||||
onTapPublisher: _showPublisherPopup,
|
onTapPublisher: _showPublisherPopup,
|
||||||
|
onTapRealm: _showRealmPopup,
|
||||||
),
|
),
|
||||||
'articles' => _PostArticleEditor(
|
'articles' => _PostArticleEditor(
|
||||||
controller: _writeController,
|
controller: _writeController,
|
||||||
@ -575,11 +604,65 @@ class _PostPublisherPopup extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _PostRealmPopup extends StatelessWidget {
|
||||||
|
final PostWriteController controller;
|
||||||
|
final List<SnRealm>? realms;
|
||||||
|
final Function onUpdate;
|
||||||
|
|
||||||
|
const _PostRealmPopup({required this.controller, this.realms, required this.onUpdate});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.face, size: 24),
|
||||||
|
const Gap(16),
|
||||||
|
Text('accountRealms', style: Theme.of(context).textTheme.titleLarge).tr(),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 20, top: 16, bottom: 12),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Symbols.close),
|
||||||
|
title: Text('postInGlobal').tr(),
|
||||||
|
subtitle: Text('postInGlobalDescription').tr(),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
onTap: () {
|
||||||
|
controller.setRealm(null);
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(height: 1),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: realms?.length ?? 0,
|
||||||
|
itemBuilder: (context, idx) {
|
||||||
|
final realm = realms![idx];
|
||||||
|
return ListTile(
|
||||||
|
title: Text(realm.name),
|
||||||
|
subtitle: Text('@${realm.alias}'),
|
||||||
|
leading: AccountImage(content: realm.avatar, radius: 18),
|
||||||
|
onTap: () {
|
||||||
|
controller.setRealm(realm);
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _PostStoryEditor extends StatelessWidget {
|
class _PostStoryEditor extends StatelessWidget {
|
||||||
final PostWriteController controller;
|
final PostWriteController controller;
|
||||||
final Function? onTapPublisher;
|
final Function? onTapPublisher;
|
||||||
|
final Function? onTapRealm;
|
||||||
|
|
||||||
const _PostStoryEditor({required this.controller, this.onTapPublisher});
|
const _PostStoryEditor({required this.controller, this.onTapPublisher, this.onTapRealm});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -588,6 +671,8 @@ class _PostStoryEditor extends StatelessWidget {
|
|||||||
constraints: const BoxConstraints(maxWidth: 640),
|
constraints: const BoxConstraints(maxWidth: 640),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
children: [
|
children: [
|
||||||
Material(
|
Material(
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
@ -601,6 +686,23 @@ class _PostStoryEditor extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Gap(10),
|
||||||
|
Material(
|
||||||
|
elevation: 1,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(24)),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
onTapRealm?.call();
|
||||||
|
},
|
||||||
|
child: AccountImage(
|
||||||
|
content: controller.realm?.avatar,
|
||||||
|
fallbackWidget: const Icon(Symbols.globe, size: 20),
|
||||||
|
radius: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
@ -365,7 +365,7 @@ class _RealmSettingsWidgetState extends State<_RealmSettingsWidget> {
|
|||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sn.client.delete('/cgi/id/realms/${widget.realm!.alias}/members/me');
|
await sn.client.delete('/cgi/id/realms/${widget.realm!.alias}/me');
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user