Post publish zone

This commit is contained in:
LittleSheep 2024-08-01 15:21:43 +08:00
parent 190bb34958
commit 7655dfdf37
7 changed files with 123 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
import 'package:solian/exts.dart'; import 'package:solian/exts.dart';
import 'package:solian/providers/auth.dart'; import 'package:solian/providers/auth.dart';
import 'package:solian/providers/content/channel.dart'; import 'package:solian/providers/content/channel.dart';
import 'package:solian/providers/content/realm.dart';
import 'package:solian/providers/relation.dart'; import 'package:solian/providers/relation.dart';
import 'package:solian/providers/theme_switcher.dart'; import 'package:solian/providers/theme_switcher.dart';
import 'package:solian/providers/websocket.dart'; import 'package:solian/providers/websocket.dart';
@ -82,6 +83,7 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isTrue) { if (auth.isAuthorized.isTrue) {
await Future.wait([ await Future.wait([
Get.find<RealmProvider>().refreshAvailableRealms(),
Get.find<ChannelProvider>().refreshAvailableChannel(), Get.find<ChannelProvider>().refreshAvailableChannel(),
Get.find<RelationshipProvider>().refreshFriendList(), Get.find<RelationshipProvider>().refreshFriendList(),
]); ]);

View File

@ -8,6 +8,7 @@ import 'package:solian/models/realm.dart';
import 'package:solian/widgets/attachments/attachment_editor.dart'; import 'package:solian/widgets/attachments/attachment_editor.dart';
import 'package:solian/widgets/posts/editor/post_editor_categories_tags.dart'; import 'package:solian/widgets/posts/editor/post_editor_categories_tags.dart';
import 'package:solian/widgets/posts/editor/post_editor_overview.dart'; import 'package:solian/widgets/posts/editor/post_editor_overview.dart';
import 'package:solian/widgets/posts/editor/post_editor_publish_zone.dart';
import 'package:solian/widgets/posts/editor/post_editor_visibility.dart'; import 'package:solian/widgets/posts/editor/post_editor_visibility.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -88,6 +89,15 @@ class PostEditorController extends GetxController {
); );
} }
Future<void> editPublishZone(BuildContext context) {
return showDialog(
context: context,
builder: (context) => PostEditorPublishZoneDialog(
controller: this,
),
);
}
Future<void> editAttachment(BuildContext context) { Future<void> editAttachment(BuildContext context) {
return showModalBottomSheet( return showModalBottomSheet(
context: context, context: context,

View File

@ -1,7 +1,24 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:solian/models/realm.dart';
import 'package:solian/providers/auth.dart'; import 'package:solian/providers/auth.dart';
class RealmProvider extends GetxController { class RealmProvider extends GetxController {
RxBool isLoading = false.obs;
RxList<Realm> availableRealms = RxList.empty(growable: true);
Future<void> refreshAvailableRealms() async {
final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw Exception('unauthorized');
isLoading.value = true;
final resp = await listAvailableRealm();
isLoading.value = false;
availableRealms.value =
resp.body.map((x) => Realm.fromJson(x)).toList().cast<Realm>();
availableRealms.refresh();
}
Future<Response> getRealm(String alias) async { Future<Response> getRealm(String alias) async {
final AuthProvider auth = Get.find(); final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); if (auth.isAuthorized.isFalse) throw Exception('unauthorized');

View File

@ -87,6 +87,9 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
if (widget.edit != null) { if (widget.edit != null) {
_editorController.editTarget = widget.edit; _editorController.editTarget = widget.edit;
} }
if (widget.realm != null) {
_editorController.realmZone.value = widget.realm;
}
} }
void cancelAction() { void cancelAction() {
@ -220,18 +223,6 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
children: [ children: [
if (_isBusy) if (_isBusy)
const LinearProgressIndicator().animate().scaleX(), const LinearProgressIndicator().animate().scaleX(),
if (_realm != null)
MaterialBanner(
leading: const Icon(Icons.group),
leadingPadding:
const EdgeInsets.only(left: 10, right: 20),
dividerColor: Colors.transparent,
content: Text(
'postInRealmNotify'
.trParams({'realm': '#${_realm!.alias}'}),
),
actions: notifyBannerActions,
),
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 16,
@ -410,6 +401,23 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
_editorController.editCategoriesAndTags(context); _editorController.editCategoriesAndTags(context);
}, },
), ),
IconButton(
icon: Obx(() {
return badges.Badge(
showBadge:
_editorController.realmZone.value != null,
position: badges.BadgePosition.topEnd(
top: -4,
end: -6,
),
child: const Icon(Icons.workspaces),
);
}),
color: Theme.of(context).colorScheme.primary,
onPressed: () {
_editorController.editPublishZone(context);
},
),
MarkdownToolbar( MarkdownToolbar(
hideImage: true, hideImage: true,
useIncludedTextField: false, useIncludedTextField: false,

View File

@ -101,6 +101,8 @@ const i18nEnglish = {
'postRestoreFromLocal': 'Restore from local', 'postRestoreFromLocal': 'Restore from local',
'postAutoSaveAt': 'Auto saved at @date', 'postAutoSaveAt': 'Auto saved at @date',
'postCategoriesAndTags': 'Categories n\' Tags', 'postCategoriesAndTags': 'Categories n\' Tags',
'postPublishZone': 'Publish Zone',
'postPublishZoneNone': 'None',
'postVisibility': 'Visibility', 'postVisibility': 'Visibility',
'postVisibilityAll': 'Everyone', 'postVisibilityAll': 'Everyone',
'postVisibilityFriends': 'Friends', 'postVisibilityFriends': 'Friends',

View File

@ -95,6 +95,8 @@ const i18nSimplifiedChinese = {
'postRestoreFromLocal': '内容从本地暂存回复', 'postRestoreFromLocal': '内容从本地暂存回复',
'postAutoSaveAt': '已自动保存于 @date', 'postAutoSaveAt': '已自动保存于 @date',
'postCategoriesAndTags': '分类与标签', 'postCategoriesAndTags': '分类与标签',
'postPublishZone': '帖子发布区',
'postPublishZoneNone': '无所属领域',
'postVisibility': '帖子可见性', 'postVisibility': '帖子可见性',
'postVisibilityAll': '所有人可见', 'postVisibilityAll': '所有人可见',
'postVisibilityFriends': '仅好友可见', 'postVisibilityFriends': '仅好友可见',

View File

@ -0,0 +1,70 @@
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/controllers/post_editor_controller.dart';
import 'package:solian/providers/content/realm.dart';
class PostEditorPublishZoneDialog extends StatelessWidget {
final PostEditorController controller;
const PostEditorPublishZoneDialog({super.key, required this.controller});
@override
Widget build(BuildContext context) {
final RealmProvider realms = Get.find();
return AlertDialog(
title: Text('postPublishZone'.tr),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() {
return DropdownButtonFormField2<int>(
isExpanded: true,
decoration: const InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
),
items: [
DropdownMenuItem<int>(
value: null,
child: Text(
'postPublishZoneNone'.tr,
style: const TextStyle(fontSize: 14),
),
),
...realms.availableRealms.map(
(x) => DropdownMenuItem<int>(
value: x.id,
child: Text(
'${x.name} (${x.alias})',
style: const TextStyle(fontSize: 14),
),
),
),
],
value: controller.realmZone.value?.id,
onChanged: (int? value) {
if (value == null) {
controller.realmZone.value = null;
} else {
controller.realmZone.value =
realms.availableRealms.firstWhere((x) => x.id == value);
}
},
buttonStyleData: const ButtonStyleData(height: 20),
menuItemStyleData: const MenuItemStyleData(height: 40),
);
}),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('confirm'.tr),
),
],
);
}
}