💄 Improve UX
This commit is contained in:
parent
3a2894b533
commit
0230ea5c79
@ -53,6 +53,9 @@
|
||||
"chatNew": "New Chat",
|
||||
"chatNewCreate": "Create a channel",
|
||||
"chatNewJoin": "Join a exists channel",
|
||||
"chatManage": "Manage Chat",
|
||||
"chatMember": "Member",
|
||||
"chatNotifySetting": "Notify Settings",
|
||||
"chatChannelUsage": "Channel",
|
||||
"chatChannelUsageCaption": "Channel is place to talk with people, one or a lot.",
|
||||
"chatChannelOrganize": "Organize a channel",
|
||||
|
@ -51,6 +51,9 @@
|
||||
"reactionAdded": "你的反应已被添加。",
|
||||
"reactionRemoved": "你的反应已被移除。",
|
||||
"chatNew": "新聊天",
|
||||
"chatManage": "管理聊天",
|
||||
"chatMember": "成员",
|
||||
"chatNotifySetting": "通知设定",
|
||||
"chatNewCreate": "新建频道",
|
||||
"chatNewJoin": "加入已有频道",
|
||||
"chatChannelUsage": "频道",
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:solian/models/account.dart';
|
||||
|
||||
class Channel {
|
||||
int id;
|
||||
DateTime createdAt;
|
||||
@ -7,9 +9,9 @@ class Channel {
|
||||
String name;
|
||||
String description;
|
||||
dynamic members;
|
||||
dynamic messages;
|
||||
dynamic calls;
|
||||
int type;
|
||||
Account account;
|
||||
int accountId;
|
||||
int realmId;
|
||||
|
||||
@ -22,9 +24,9 @@ class Channel {
|
||||
required this.name,
|
||||
required this.description,
|
||||
this.members,
|
||||
this.messages,
|
||||
this.calls,
|
||||
required this.type,
|
||||
required this.account,
|
||||
required this.accountId,
|
||||
required this.realmId,
|
||||
});
|
||||
@ -38,9 +40,9 @@ class Channel {
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
members: json["members"],
|
||||
messages: json["messages"],
|
||||
calls: json["calls"],
|
||||
type: json["type"],
|
||||
account: Account.fromJson(json["account"]),
|
||||
accountId: json["account_id"],
|
||||
realmId: json["realm_id"],
|
||||
);
|
||||
@ -54,9 +56,9 @@ class Channel {
|
||||
"name": name,
|
||||
"description": description,
|
||||
"members": members,
|
||||
"messages": messages,
|
||||
"calls": calls,
|
||||
"type": type,
|
||||
"account": account,
|
||||
"account_id": accountId,
|
||||
"realm_id": realmId,
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ class ChatProvider {
|
||||
|
||||
await auth.refreshToken();
|
||||
|
||||
var ori = getRequestUri('messaging', '/api/unified');
|
||||
var ori = getRequestUri('messaging', '/api/ws');
|
||||
var uri = Uri(
|
||||
scheme: ori.scheme.replaceFirst('http', 'ws'),
|
||||
host: ori.host,
|
||||
|
@ -4,13 +4,14 @@ import 'package:solian/models/post.dart';
|
||||
import 'package:solian/screens/account.dart';
|
||||
import 'package:solian/screens/chat/chat.dart';
|
||||
import 'package:solian/screens/chat/index.dart';
|
||||
import 'package:solian/screens/chat/manage.dart';
|
||||
import 'package:solian/screens/chat/channel/channel_editor.dart';
|
||||
import 'package:solian/screens/explore.dart';
|
||||
import 'package:solian/screens/notification.dart';
|
||||
import 'package:solian/screens/posts/comment_editor.dart';
|
||||
import 'package:solian/screens/posts/moment_editor.dart';
|
||||
import 'package:solian/screens/posts/screen.dart';
|
||||
import 'package:solian/screens/signin.dart';
|
||||
import 'package:solian/widgets/chat/channel_editor.dart';
|
||||
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
@ -27,13 +28,18 @@ final router = GoRouter(
|
||||
GoRoute(
|
||||
path: '/chat/create',
|
||||
name: 'chat.channel.editor',
|
||||
builder: (context, state) => ChannelEditor(editing: state.extra as Channel?),
|
||||
builder: (context, state) => ChannelEditorScreen(editing: state.extra as Channel?),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat/c/:channel',
|
||||
name: 'chat.channel',
|
||||
builder: (context, state) => ChatScreen(alias: state.pathParameters['channel'] as String),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/chat/c/:channel/manage',
|
||||
name: 'chat.channel.manage',
|
||||
builder: (context, state) => ChatManageScreen(channel: state.extra as Channel),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
|
@ -12,16 +12,16 @@ import 'package:solian/widgets/indent_wrapper.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChannelEditor extends StatefulWidget {
|
||||
class ChannelEditorScreen extends StatefulWidget {
|
||||
final Channel? editing;
|
||||
|
||||
const ChannelEditor({super.key, this.editing});
|
||||
const ChannelEditorScreen({super.key, this.editing});
|
||||
|
||||
@override
|
||||
State<ChannelEditor> createState() => _ChannelEditorState();
|
||||
State<ChannelEditorScreen> createState() => _ChannelEditorScreenState();
|
||||
}
|
||||
|
||||
class _ChannelEditorState extends State<ChannelEditor> {
|
||||
class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
final _aliasController = TextEditingController();
|
||||
final _nameController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
@ -9,6 +9,7 @@ import 'package:solian/utils/service_url.dart';
|
||||
import 'package:solian/widgets/chat/chat_new.dart';
|
||||
import 'package:solian/widgets/indent_wrapper.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:solian/widgets/notification_notifier.dart';
|
||||
import 'package:solian/widgets/signin_required.dart';
|
||||
|
||||
class ChatIndexScreen extends StatefulWidget {
|
||||
@ -63,6 +64,7 @@ class _ChatIndexScreenState extends State<ChatIndexScreen> {
|
||||
|
||||
return IndentWrapper(
|
||||
title: AppLocalizations.of(context)!.chat,
|
||||
appBarActions: const [NotificationButton()],
|
||||
floatingActionButton: FutureBuilder(
|
||||
future: auth.isAuthorized(),
|
||||
builder: (context, snapshot) {
|
||||
|
96
lib/screens/chat/manage.dart
Normal file
96
lib/screens/chat/manage.dart
Normal file
@ -0,0 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:solian/models/channel.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/router.dart';
|
||||
import 'package:solian/widgets/indent_wrapper.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class ChatManageScreen extends StatefulWidget {
|
||||
final Channel channel;
|
||||
|
||||
const ChatManageScreen({super.key, required this.channel});
|
||||
|
||||
@override
|
||||
State<ChatManageScreen> createState() => _ChatManageScreenState();
|
||||
}
|
||||
|
||||
class _ChatManageScreenState extends State<ChatManageScreen> {
|
||||
bool isOwned = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
Future.delayed(Duration.zero, () async {
|
||||
final auth = context.read<AuthProvider>();
|
||||
final prof = await auth.getProfiles();
|
||||
|
||||
setState(() {
|
||||
isOwned = prof['id'] == widget.channel.account.externalId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final authorizedItems = [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: Text(AppLocalizations.of(context)!.settings),
|
||||
onTap: () async {
|
||||
router.pushNamed('chat.channel.editor', extra: widget.channel).then((did) {
|
||||
if (did == true) {
|
||||
if (router.canPop()) router.pop(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
return IndentWrapper(
|
||||
title: AppLocalizations.of(context)!.chatManage,
|
||||
hideDrawer: true,
|
||||
noSafeArea: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
const CircleAvatar(
|
||||
radius: 24,
|
||||
backgroundColor: Colors.teal,
|
||||
child: Icon(Icons.tag, color: Colors.white),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(widget.channel.name, style: Theme.of(context).textTheme.bodyLarge),
|
||||
Text(widget.channel.description, style: Theme.of(context).textTheme.bodySmall),
|
||||
])
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(thickness: 0.3),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.edit_notifications),
|
||||
title: Text(AppLocalizations.of(context)!.chatNotifySetting),
|
||||
onTap: () {},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.supervisor_account),
|
||||
title: Text(AppLocalizations.of(context)!.chatMember),
|
||||
onTap: () {},
|
||||
),
|
||||
...(isOwned ? authorizedItems : List.empty()),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
||||
|
||||
return IndentWrapper(
|
||||
noSafeArea: true,
|
||||
hideDrawer: true,
|
||||
title: AppLocalizations.of(context)!.notification,
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => nty.fetch(auth),
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:solian/models/channel.dart';
|
||||
import 'package:solian/router.dart';
|
||||
|
||||
@ -13,41 +12,17 @@ class ChannelAction extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
MenuAnchor(
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.settings),
|
||||
const SizedBox(width: 12),
|
||||
Text(AppLocalizations.of(context)!.settings),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
router.pushNamed('chat.channel.editor', extra: channel).then((did) {
|
||||
if(did == true) onUpdate();
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
builder: (BuildContext context, MenuController controller, Widget? child) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
focusNode: _focusNode,
|
||||
style: TextButton.styleFrom(shape: const CircleBorder()),
|
||||
icon: const Icon(Icons.more_horiz),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
router.pushNamed(
|
||||
'chat.channel.manage',
|
||||
extra: channel,
|
||||
pathParameters: {'channel': channel.alias},
|
||||
);
|
||||
},
|
||||
focusNode: _focusNode,
|
||||
style: TextButton.styleFrom(shape: const CircleBorder()),
|
||||
icon: const Icon(Icons.more_horiz),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ class ChatMaintainer extends StatefulWidget {
|
||||
|
||||
class _ChatMaintainerState extends State<ChatMaintainer> {
|
||||
void connect() {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
|
||||
final notify = ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.connectingServer),
|
||||
@ -73,8 +75,6 @@ class _ChatMaintainerState extends State<ChatMaintainer> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
|
||||
return widget.child;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:solian/models/reaction.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
@ -106,7 +107,7 @@ class _ReactionActionPopupState extends State<ReactionActionPopup> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 20),
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 20, bottom: 12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
@ -118,7 +119,7 @@ class _ReactionActionPopupState extends State<ReactionActionPopup> {
|
||||
),
|
||||
),
|
||||
),
|
||||
_isSubmitting ? const LinearProgressIndicator() : Container(),
|
||||
_isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: reactions.length,
|
||||
|
Loading…
Reference in New Issue
Block a user