diff --git a/lib/application/store/im_state.dart b/lib/application/store/im_state.dart index b783c24c..75374715 100644 --- a/lib/application/store/im_state.dart +++ b/lib/application/store/im_state.dart @@ -1,6 +1,6 @@ // ignore_for_file: depend_on_referenced_packages import 'dart:async'; -import 'package:dtim/infra/pages/channel/setting/key_verification_dialog.dart'; +import 'package:dtim/infra/pages/chat/channel/setting/key_verification_dialog.dart'; import 'package:dtim/domain/utils/functions.dart'; import 'package:desktop_notifications/desktop_notifications.dart'; import 'package:easy_debounce/easy_debounce.dart'; diff --git a/lib/infra/components/avatar.dart b/lib/infra/components/avatar.dart index da2f2a4b..a06048a0 100644 --- a/lib/infra/components/avatar.dart +++ b/lib/infra/components/avatar.dart @@ -22,6 +22,7 @@ class Avatar extends StatelessWidget { final double fontSize; final Color? bg; final Color? color; + final double radius; const Avatar({ required this.id, @@ -31,10 +32,11 @@ class Avatar extends StatelessWidget { this.onTap, this.client, this.fontSize = 18, - Key? key, + this.radius = 3, + super.key, this.bg, this.color, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -81,7 +83,7 @@ class Avatar extends StatelessWidget { } else { container = id == "" ? CircleAvatar( - radius: 3, + radius: radius, child: Container( width: size, height: size, @@ -96,6 +98,7 @@ class Avatar extends StatelessWidget { size, color: color, bg: bg, + radius: radius, ); } @@ -113,8 +116,9 @@ class BaseAvatar extends StatefulWidget { final double avatarWidth; final Color? bg; final Color? color; + final double radius; - const BaseAvatar(this.avatarSrc, this.online, this.avatarWidth, {super.key, this.bg, this.color}); + const BaseAvatar(this.avatarSrc, this.online, this.avatarWidth, {super.key, this.bg, this.color, this.radius = 3}); @override State createState() => _BaseAvatarState(); @@ -125,16 +129,16 @@ class _BaseAvatarState extends State { buildCtx(BuildContext context) { final constTheme = Theme.of(context).extension()!; - final imgw = (widget.avatarWidth * 0.7).toInt(); + final imgw = (widget.avatarWidth * 0.7 - widget.radius/4).toInt(); final imgbg = widget.color ?? constTheme.centerChannelColor; final boxBg = widget.bg ?? constTheme.centerChannelColor.withOpacity(0.1); final img = Identicon(fg: [imgbg.red, imgbg.green, imgbg.blue]).generate( getUserShortId(widget.avatarSrc), - scale: (widget.avatarWidth / 50).ceil(), + scale: (widget.avatarWidth / 6).ceil(), ); ctx = Container( - decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: boxBg), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(widget.radius), color: boxBg), padding: EdgeInsets.all((widget.avatarWidth - imgw) / 2), alignment: Alignment.topLeft, child: Image.memory( @@ -178,11 +182,11 @@ class BaseAvatarWithPop extends StatefulWidget { this.name, this.online, this.avatarWidth, { - Key? key, + super.key, this.bg, this.color, this.mxContent, - }) : super(key: key); + }); @override State createState() => _BaseAvatarWithPopState(); diff --git a/lib/infra/components/components.dart b/lib/infra/components/components.dart index 95ee3b26..3de74795 100644 --- a/lib/infra/components/components.dart +++ b/lib/infra/components/components.dart @@ -1,5 +1,4 @@ export 'app_bar.dart'; -export 'channel_list.dart'; export 'move_window.dart'; export 'direct_chat.dart'; export 'avatar.dart'; diff --git a/lib/infra/components/hover_list_item.dart b/lib/infra/components/hover_list_item.dart index 8f8dd9f3..cc27028b 100644 --- a/lib/infra/components/hover_list_item.dart +++ b/lib/infra/components/hover_list_item.dart @@ -1,3 +1,4 @@ +import 'package:dtim/application/chain/wetee/wetee_gen/types/frame_support/dispatch/raw_origin.dart'; import 'package:flutter/material.dart'; class HoverListItem extends StatefulWidget { @@ -9,9 +10,11 @@ class HoverListItem extends StatefulWidget { final Widget? trailing; final Widget child; final String subkey; + final double radius; + final EdgeInsetsGeometry? margin; const HoverListItem({ - Key? key, + super.key, required this.onPressed, required this.child, this.trailing, @@ -20,7 +23,9 @@ class HoverListItem extends StatefulWidget { this.ishover, required this.subkey, this.onHover, - }) : super(key: key); + this.radius = 0, + this.margin, + }); @override HoverListItemState createState() => HoverListItemState(); @@ -50,7 +55,11 @@ class HoverListItemState extends State { behavior: HitTestBehavior.translucent, onTap: () => widget.onPressed(), child: Container( - color: calcHover ? widget.hoverColor : widget.color, + margin: widget.margin, + decoration: BoxDecoration( + borderRadius: widget.radius > 0 ? BorderRadius.circular(widget.radius) : BorderRadius.zero, + color: calcHover ? widget.hoverColor : widget.color, + ), child: widget.trailing == null ? widget.child : Row( diff --git a/lib/infra/components/me_pop.dart b/lib/infra/components/me_pop.dart index d13bdcd2..f7e475ed 100644 --- a/lib/infra/components/me_pop.dart +++ b/lib/infra/components/me_pop.dart @@ -26,11 +26,11 @@ class MePop extends StatefulWidget { this.name, this.online, this.avatarWidth, { - Key? key, + super.key, this.bg, this.color, this.mxContent, - }) : super(key: key); + }); @override State createState() => _MePopState(); @@ -54,7 +54,8 @@ class _MePopState extends State { color: widget.color, id: widget.id, mxContent: widget.mxContent, - size: 40.w, + size: widget.avatarWidth, + radius: widget.avatarWidth/2, ), menuBuilder: () => Container( width: 270.w, diff --git a/lib/infra/components/model_bar.dart b/lib/infra/components/model_bar.dart index 375cb950..74185c80 100644 --- a/lib/infra/components/model_bar.dart +++ b/lib/infra/components/model_bar.dart @@ -11,10 +11,9 @@ class ModelBar extends StatelessWidget implements PreferredSizeWidget { final String _title; final Widget? tools; final Function? onBack; - ModelBar({Key? key, this.onBack, this.tools, String? title, double? height}) - : _height = (height ?? 50.w).toInt().toDouble(), - _title = title ?? "", - super(key: key); + ModelBar({super.key, this.onBack, this.tools, String? title, double? height}) + : _height = (height ?? 55.w).toInt().toDouble(), + _title = title ?? ""; @override Widget build(BuildContext context) { diff --git a/lib/infra/components/sider_bar.dart b/lib/infra/components/sider_bar.dart index 363f3cf3..638ef5d1 100644 --- a/lib/infra/components/sider_bar.dart +++ b/lib/infra/components/sider_bar.dart @@ -9,101 +9,104 @@ class SiderBarItem extends StatelessWidget { final String name; final bool selected; final Function? onTap; + final Color? bg; - const SiderBarItem(this.name, {super.key, this.icon, required this.selected, this.onTap, this.img}); + const SiderBarItem(this.name, {super.key, this.icon, required this.selected, this.onTap, this.img, this.bg}); @override Widget build(BuildContext context) { final constTheme = Theme.of(context).extension()!; - return InkWell( - onTap: () { - onTap?.call(); - }, - child: Container( - width: 52.w, - height: 52.w, - padding: EdgeInsets.only(top: 4.w), - decoration: BoxDecoration( - color: selected ? constTheme.sidebarText.withOpacity(0.1) : Colors.transparent, - borderRadius: BorderRadius.circular(6.w), - ), - margin: EdgeInsets.only(bottom: 5.w), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - icon != null - ? Icon( - icon!, - color: constTheme.sidebarText, - size: 20.w, - ) - : (img != null - ? Image.network( - img!, - width: 20.w, - height: 20.w, - fit: BoxFit.cover, - color: constTheme.sidebarText, - loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { - if (loadingProgress == null) return child; - return Container( - width: 20.w, - height: 20.w, - decoration: BoxDecoration( - color: constTheme.sidebarText, - borderRadius: BorderRadius.all(Radius.circular(3.w)), - ), - child: Center( - child: Text( - name[0], - style: TextStyle( - fontSize: 12.w, - color: constTheme.sidebarBg, - fontWeight: FontWeight.bold, + final bgc = bg ?? constTheme.sidebarText.withOpacity(0.1); + return Padding( + padding: EdgeInsets.only(bottom: 5.w), + child: InkWell( + onTap: () { + onTap?.call(); + }, + child: Container( + width: 52.w, + padding: EdgeInsets.only(top: 10.w, bottom: 6.w), + decoration: BoxDecoration( + color: selected ? bgc : Colors.transparent, + borderRadius: BorderRadius.circular(6.w), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + icon != null + ? Icon( + icon!, + color: constTheme.sidebarText, + size: 16.w, + ) + : (img != null + ? Image.network( + img!, + width: 16.w, + height: 16.w, + fit: BoxFit.cover, + color: constTheme.sidebarText, + loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) return child; + return Container( + width: 16.w, + height: 16.w, + decoration: BoxDecoration( + color: constTheme.sidebarText, + borderRadius: BorderRadius.all(Radius.circular(3.w)), + ), + child: Center( + child: Text( + name[0], + style: TextStyle( + fontSize: 12.w, + color: constTheme.sidebarBg, + fontWeight: FontWeight.bold, + ), ), ), - ), - ); - }, - errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return Container( - width: 20.w, - height: 20.w, - decoration: BoxDecoration( - color: constTheme.sidebarText, - borderRadius: BorderRadius.all(Radius.circular(3.w)), - ), - child: Center( - child: Text( - name[0], - style: TextStyle( - fontSize: 12.w, - color: constTheme.sidebarBg, - fontWeight: FontWeight.bold, + ); + }, + errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { + return Container( + width: 20.w, + height: 20.w, + decoration: BoxDecoration( + color: constTheme.sidebarText, + borderRadius: BorderRadius.all(Radius.circular(3.w)), + ), + child: Center( + child: Text( + name[0], + style: TextStyle( + fontSize: 12.w, + color: constTheme.sidebarBg, + fontWeight: FontWeight.bold, + ), ), ), - ), - ); - }, - ) - : SizedBox( - width: 20.w, - height: 20.w, - )), - SizedBox(height: 3.w), - Container( - padding: EdgeInsets.symmetric(horizontal: 3.w), - height: 14.w, - child: Text( - name.split("&").first, - style: TextStyle( - color: constTheme.sidebarText, - fontSize: 10.w, + ); + }, + ) + : SizedBox( + width: 20.w, + height: 20.w, + )), + // SizedBox(height: 3.w), + Container( + padding: EdgeInsets.symmetric(horizontal: 3.w), + height: 14.w, + child: Text( + name.split("&").first, + style: TextStyle( + color: constTheme.sidebarText, + fontSize: 10.w, + ), + overflow: TextOverflow.ellipsis, ), - overflow: TextOverflow.ellipsis, ), - ), - ], + ], + ), ), ), ); diff --git a/lib/infra/components/window.dart b/lib/infra/components/window.dart index 982a96de..2d3df6df 100644 --- a/lib/infra/components/window.dart +++ b/lib/infra/components/window.dart @@ -1,7 +1,9 @@ import 'dart:io'; +import 'dart:ui'; import 'package:dtim/application/service/apis/system_api.dart'; import 'package:dtim/application/store/theme.dart'; +import 'package:dtim/domain/utils/screen/screen.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:window_manager/window_manager.dart'; @@ -44,20 +46,18 @@ class _AeroFrameState extends State with WindowListener { final constTheme = Theme.of(context).extension()!; return Container( decoration: BoxDecoration( - color: constTheme.sidebarBg.withOpacity(0.90), - border: Border.all( - color: Theme.of(context).dividerColor.withOpacity(0.3), - width: (_isMaximized || _isFullScreen) ? 0 : 1, - ), - borderRadius: BorderRadius.circular( - (_isMaximized || _isFullScreen) ? 0 : 14 - ), + color: constTheme.sidebarBg.withOpacity(0.68), + // border: Border.all( + // color: Theme.of(context).dividerColor.withOpacity(0.3), + // width: (_isMaximized || _isFullScreen) ? 0 : 1, + // ), + borderRadius: BorderRadius.circular((_isMaximized || _isFullScreen) ? 0 : 14), boxShadow: [ if (!_isMaximized && !_isFullScreen) BoxShadow( color: Colors.black.withOpacity(0.4), // offset: Offset(0.0, _isFocused ? 4 : 2), - blurRadius: 5 + blurRadius: 5, ), ], ), @@ -67,14 +67,17 @@ class _AeroFrameState extends State with WindowListener { borderRadius: BorderRadius.circular( (_isMaximized || _isFullScreen) ? 0 : 16, ), - child: Container( - margin: const EdgeInsets.all(6), - child: ClipRRect( - clipBehavior: Clip.hardEdge, - borderRadius: BorderRadius.circular( - (_isMaximized || _isFullScreen) ? 0 : 12, + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: Container( + margin: EdgeInsets.all(5.w), + child: ClipRRect( + clipBehavior: Clip.hardEdge, + borderRadius: BorderRadius.circular( + (_isMaximized || _isFullScreen) ? 0 : 12, + ), + child: widget.child, ), - child: widget.child, ), ), ), diff --git a/lib/infra/pages/channel/bar.dart b/lib/infra/pages/chat/channel/bar.dart similarity index 100% rename from lib/infra/pages/channel/bar.dart rename to lib/infra/pages/chat/channel/bar.dart diff --git a/lib/infra/pages/channel/bar_menu.dart b/lib/infra/pages/chat/channel/bar_menu.dart similarity index 100% rename from lib/infra/pages/channel/bar_menu.dart rename to lib/infra/pages/chat/channel/bar_menu.dart diff --git a/lib/infra/pages/channel/chat.dart b/lib/infra/pages/chat/channel/chat.dart similarity index 89% rename from lib/infra/pages/channel/chat.dart rename to lib/infra/pages/chat/channel/chat.dart index f355942d..fbed885c 100644 --- a/lib/infra/pages/channel/chat.dart +++ b/lib/infra/pages/chat/channel/chat.dart @@ -28,7 +28,7 @@ import 'msg.dart'; class ChannelDetailPage extends StatefulWidget { String channerlID; - ChannelDetailPage({Key? key, required this.channerlID}) : super(key: key); + ChannelDetailPage({super.key, required this.channerlID}); @override State createState() => _ChannelDetailPageState(); @@ -229,7 +229,10 @@ class _ChannelDetailPageState extends State with WindowListen Widget build(BuildContext context) { if (room == null) return Container(); final constTheme = Theme.of(context).extension()!; - final size = BoxConstraints(minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w); + final size = BoxConstraints(minWidth: 28.w, maxWidth: 28.w, minHeight: 28.w, maxHeight: 28.w); + final iconStyle = IconButton.styleFrom( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.w)), + ); return Scaffold( appBar: ChannelBar( room: room!, @@ -279,40 +282,33 @@ class _ChannelDetailPageState extends State with WindowListen }, padding: EdgeInsets.zero, constraints: size, - style: IconButton.styleFrom( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.w)), - ), + style: iconStyle, tooltip: "meeting", icon: Icon(AppIcons.meeting_board, color: constTheme.centerChannelColor, size: 21.w), ), ), if (room!.isDirectChat) - Padding( - padding: EdgeInsets.only(right: 5.w), - child: IconButton( - onPressed: () async { - // final voip = im.currentState!.webrtcTool!.voip; - // final success = await waitFutureLoading( - // context: context, - // future: () => voip.requestTurnServerCredentials(), - // ); - // if (success.result == null) { - // BotToast.showText(text: L10n.of(context)!.turnError); - // } - // try { - // await voip.inviteToCall(room!.id, link.CallType.kVoice); - // } catch (e) { - // BotToast.showText(text: e.toLocalizedString(globalCtx())); - // } - }, - padding: EdgeInsets.zero, - constraints: size, - style: IconButton.styleFrom( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.w)), - ), - tooltip: "voice call", - icon: Icon(Icons.call_rounded, color: constTheme.centerChannelColor, size: 21.w), - ), + IconButton( + onPressed: () async { + // final voip = im.currentState!.webrtcTool!.voip; + // final success = await waitFutureLoading( + // context: context, + // future: () => voip.requestTurnServerCredentials(), + // ); + // if (success.result == null) { + // BotToast.showText(text: L10n.of(context)!.turnError); + // } + // try { + // await voip.inviteToCall(room!.id, link.CallType.kVoice); + // } catch (e) { + // BotToast.showText(text: e.toLocalizedString(globalCtx())); + // } + }, + padding: EdgeInsets.zero, + constraints: size, + style: iconStyle, + tooltip: "voice call", + icon: Icon(Icons.call_rounded, color: constTheme.centerChannelColor, size: 21.w), ), // IconButton( // onPressed: () async { @@ -354,9 +350,7 @@ class _ChannelDetailPageState extends State with WindowListen builder: (BuildContext context, snapshot) => IconButton( padding: EdgeInsets.zero, constraints: size, - style: IconButton.styleFrom( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.w)), - ), + style: iconStyle, tooltip: room!.encrypted ? L10n.of(context)!.encrypted : L10n.of(context)!.encryptionNotEnabled, icon: Icon( room!.encrypted ? Icons.lock_rounded : Icons.lock_open_rounded, @@ -375,18 +369,13 @@ class _ChannelDetailPageState extends State with WindowListen ); }, ), - SizedBox(width: 2.w), IconButton( onPressed: () async { showModelOrPage(context, "/channel_setting/${Uri.encodeComponent(room!.id)}/info"); }, padding: EdgeInsets.zero, - constraints: BoxConstraints(minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w), - style: IconButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(4.w), - ), - ), + constraints: size, + style: iconStyle, tooltip: "info", icon: Icon( Icons.info_outline, @@ -394,7 +383,7 @@ class _ChannelDetailPageState extends State with WindowListen size: 21.w, ), ), - SizedBox(width: 9.w), + SizedBox(width: 7.w), ], ), ), diff --git a/lib/infra/pages/channel/create.dart b/lib/infra/pages/chat/channel/create.dart similarity index 100% rename from lib/infra/pages/channel/create.dart rename to lib/infra/pages/chat/channel/create.dart diff --git a/lib/infra/pages/channel/create_private.dart b/lib/infra/pages/chat/channel/create_private.dart similarity index 100% rename from lib/infra/pages/channel/create_private.dart rename to lib/infra/pages/chat/channel/create_private.dart diff --git a/lib/infra/pages/channel/input.dart b/lib/infra/pages/chat/channel/input.dart similarity index 100% rename from lib/infra/pages/channel/input.dart rename to lib/infra/pages/chat/channel/input.dart diff --git a/lib/infra/pages/channel/msg.dart b/lib/infra/pages/chat/channel/msg.dart similarity index 98% rename from lib/infra/pages/channel/msg.dart rename to lib/infra/pages/chat/channel/msg.dart index 3d375b5c..cc5ffa34 100644 --- a/lib/infra/pages/channel/msg.dart +++ b/lib/infra/pages/chat/channel/msg.dart @@ -18,8 +18,7 @@ class Msg extends StatefulWidget { final link.Client client; final link.Timeline timeline; - const Msg({Key? key, required this.event, required this.client, this.preEvent, required this.timeline}) - : super(key: key); + const Msg({super.key, required this.event, required this.client, this.preEvent, required this.timeline}); @override State createState() => _MsgState(); @@ -234,7 +233,7 @@ class _MsgState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (showAvatar) SizedBox(height: 8.w), + if (showAvatar) SizedBox(height: 5.w), if (showAvatar) RichText( text: TextSpan( @@ -259,7 +258,7 @@ class _MsgState extends State { SizedBox(height: 3.w), renderBody(event), Reacs(event, widget.timeline, client: widget.client), - SizedBox(height: 5.w), + SizedBox(height: 3.w), ], ), ), diff --git a/lib/infra/pages/channel/setting/details.dart b/lib/infra/pages/chat/channel/setting/details.dart similarity index 100% rename from lib/infra/pages/channel/setting/details.dart rename to lib/infra/pages/chat/channel/setting/details.dart diff --git a/lib/infra/pages/channel/setting/encryption.dart b/lib/infra/pages/chat/channel/setting/encryption.dart similarity index 100% rename from lib/infra/pages/channel/setting/encryption.dart rename to lib/infra/pages/chat/channel/setting/encryption.dart diff --git a/lib/infra/pages/channel/setting/key_verification_dialog.dart b/lib/infra/pages/chat/channel/setting/key_verification_dialog.dart similarity index 100% rename from lib/infra/pages/channel/setting/key_verification_dialog.dart rename to lib/infra/pages/chat/channel/setting/key_verification_dialog.dart diff --git a/lib/infra/pages/channel/setting/members.dart b/lib/infra/pages/chat/channel/setting/members.dart similarity index 100% rename from lib/infra/pages/channel/setting/members.dart rename to lib/infra/pages/chat/channel/setting/members.dart diff --git a/lib/infra/pages/channel/setting/setting.dart b/lib/infra/pages/chat/channel/setting/setting.dart similarity index 96% rename from lib/infra/pages/channel/setting/setting.dart rename to lib/infra/pages/chat/channel/setting/setting.dart index ed57f337..fb24ebb5 100644 --- a/lib/infra/pages/channel/setting/setting.dart +++ b/lib/infra/pages/chat/channel/setting/setting.dart @@ -24,7 +24,7 @@ class ChannelSettingPage extends StatefulWidget { final String id; final String t; final Function? closeModel; - const ChannelSettingPage({Key? key, required this.id, this.closeModel, required this.t}) : super(key: key); + const ChannelSettingPage({super.key, required this.id, this.closeModel, required this.t}); @override State createState() => _ChannelSettingPageState(); @@ -103,6 +103,7 @@ class _ChannelSettingPageState extends State with TickerProv tabs: titleList.map((e) => Tab(text: e)).toList(), isScrollable: true, dividerColor: Colors.transparent, + tabAlignment: TabAlignment.start, indicator: MaterialIndicator( color: constTheme.sidebarTextActiveBorder, strokeWidth: 10, diff --git a/lib/infra/components/channel_list.dart b/lib/infra/pages/chat/channel_list.dart similarity index 86% rename from lib/infra/components/channel_list.dart rename to lib/infra/pages/chat/channel_list.dart index a7df87eb..b5fa855d 100644 --- a/lib/infra/components/channel_list.dart +++ b/lib/infra/pages/chat/channel_list.dart @@ -13,11 +13,11 @@ import 'package:dtim/router.dart'; import 'package:dtim/application/store/app/app.dart'; import 'package:dtim/application/store/theme.dart'; import 'package:dtim/domain/utils/screen/screen.dart'; -import 'hover_list_item.dart'; -import 'loading_dialog.dart'; +import '../../components/hover_list_item.dart'; +import '../../components/loading_dialog.dart'; class ChannelList extends StatefulWidget { - const ChannelList({Key? key}) : super(key: key); + const ChannelList({super.key}); @override State createState() => _ChannelListState(); @@ -54,8 +54,10 @@ class _ChannelListState extends State { key: Key(chat.id), subkey: "DirectChat${chat.id}", ishover: index == hover, - color: currentId == chat.id ? constTheme.sidebarText.withOpacity(0.08) : Colors.transparent, - hoverColor: constTheme.sidebarText.withOpacity(0.08), + color: currentId == chat.id ? constTheme.sidebarTextActiveBorder.withOpacity(0.09) : Colors.transparent, + hoverColor: currentId == chat.id ? constTheme.sidebarTextActiveBorder.withOpacity(0.09):constTheme.centerChannelColor.withOpacity(0.08), + radius: 5.w, + margin: EdgeInsets.only(left: 5.w, right: 5.w, bottom: 2.w), onPressed: () async { org.setChannelId(chat.id); }, @@ -69,7 +71,7 @@ class _ChannelListState extends State { context: context, color: constTheme.sidebarBg, elevation: 0, - shape: Border.all(color: constTheme.sidebarText.withOpacity(0.08)), + shape: Border.all(color: constTheme.centerChannelColor.withOpacity(0.08)), position: RelativeRect.fromLTRB( offset.dx, offset.dy, @@ -144,21 +146,16 @@ class _ChannelListState extends State { child: Container( height: 29.w, padding: EdgeInsets.only(right: 12.w, left: 12.w), - child: Icon(Icons.adaptive.more, size: 17.w, color: constTheme.sidebarText.withAlpha(155)), - ), - ), - child: Container( - decoration: BoxDecoration( - border: Border( - left: BorderSide( - width: 2.w, - color: currentId == chat.id ? constTheme.sidebarTextActiveBorder : Colors.transparent, - ), + child: Icon( + Icons.adaptive.more, + size: 17.w, + color: constTheme.centerChannelColor.withAlpha(155), ), ), - height: 35.w, + ), + child: SizedBox( + height: 45.w, width: double.maxFinite, - // padding: EdgeInsets.symmetric(vertical: 5.w, horizontal: 12.w), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -183,7 +180,7 @@ class _ChannelListState extends State { child: Icon( chat.encrypted ? Icons.private_connectivity : Icons.all_inclusive_sharp, size: chat.encrypted ? 24.w : 19.w, - color: chat.isUnreadOrInvited ? constTheme.sidebarUnreadText : constTheme.sidebarText, + color: chat.isUnreadOrInvited ? constTheme.sidebarUnreadText : constTheme.centerChannelColor, ), ), ), @@ -197,7 +194,7 @@ class _ChannelListState extends State { style: TextStyle( fontSize: 15.w, fontWeight: chat.isUnreadOrInvited ? FontWeight.bold : FontWeight.normal, - color: chat.isUnreadOrInvited ? constTheme.sidebarUnreadText : constTheme.sidebarText, + color: chat.isUnreadOrInvited ? constTheme.sidebarUnreadText : constTheme.centerChannelColor, ), ), ), @@ -219,15 +216,17 @@ class _ChannelListState extends State { padding: EdgeInsets.all(10.w), decoration: BoxDecoration( border: Border( - bottom: !hideBorder ? BorderSide(color: constTheme.sidebarText.withOpacity(0.08)) : BorderSide.none), + bottom: + !hideBorder ? BorderSide(color: constTheme.centerChannelColor.withOpacity(0.08)) : BorderSide.none), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(width: 10.w), - Icon(icon, color: constTheme.sidebarText.withOpacity(0.7), size: 16.w), + Icon(icon, color: constTheme.centerChannelColor.withOpacity(0.7), size: 16.w), SizedBox(width: 6.w), - Text(name, style: TextStyle(color: constTheme.sidebarText.withOpacity(0.7), fontSize: 12.w, height: 1)), + Text(name, + style: TextStyle(color: constTheme.centerChannelColor.withOpacity(0.7), fontSize: 12.w, height: 1)), SizedBox(width: 10.w), ], ), diff --git a/lib/infra/pages/org/org.dart b/lib/infra/pages/chat/chat.dart similarity index 95% rename from lib/infra/pages/org/org.dart rename to lib/infra/pages/chat/chat.dart index 3d3ae5cd..cceb9a16 100644 --- a/lib/infra/pages/org/org.dart +++ b/lib/infra/pages/chat/chat.dart @@ -9,12 +9,12 @@ import 'package:dtim/application/store/app/org.dart'; import 'package:dtim/domain/utils/screen/screen.dart'; import 'package:dtim/infra/components/components.dart'; import 'package:dtim/application/store/theme.dart'; -import '../channel/chat.dart'; -import 'org_view.dart'; +import 'channel/chat.dart'; +import 'chat_view.dart'; @RoutePage(name: "orgRoute") class OrgPage extends StatefulWidget { - const OrgPage({Key? key}) : super(key: key); + const OrgPage({super.key}); @override State createState() => _OrgPageState(); @@ -43,7 +43,7 @@ class _OrgPageState extends State { color: constTheme.centerChannelBg, borderRadius: BorderRadius.circular(10.w) ), - margin: EdgeInsets.only(left: 5.w), + margin: EdgeInsets.only(left: 3.w), child: OrgViewPage(key: const Key("OrgViewPage"), width: leftWidth), ), GestureDetector( @@ -53,7 +53,7 @@ class _OrgPageState extends State { children: [ Container( color: Colors.transparent, - width: 3.w, + width: 4.w, height: double.infinity, ), const SizedBox(width: 1, height: double.infinity), diff --git a/lib/infra/pages/org/org_menu.dart b/lib/infra/pages/chat/chat_menu.dart similarity index 100% rename from lib/infra/pages/org/org_menu.dart rename to lib/infra/pages/chat/chat_menu.dart diff --git a/lib/infra/pages/org/org_mobile.dart b/lib/infra/pages/chat/chat_mobile.dart similarity index 95% rename from lib/infra/pages/org/org_mobile.dart rename to lib/infra/pages/chat/chat_mobile.dart index 9e1a6b7a..4de653c1 100644 --- a/lib/infra/pages/org/org_mobile.dart +++ b/lib/infra/pages/chat/chat_mobile.dart @@ -1,7 +1,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; -import 'org_view.dart'; +import 'chat_view.dart'; @RoutePage(name: "orgMobileRoute") class OrgMobilePage extends StatefulWidget { diff --git a/lib/infra/pages/chat/chat_view.dart b/lib/infra/pages/chat/chat_view.dart new file mode 100644 index 00000000..f270e493 --- /dev/null +++ b/lib/infra/pages/chat/chat_view.dart @@ -0,0 +1,487 @@ +import 'dart:async'; +import 'package:dtim/application/store/app/org.dart'; +import 'package:dtim/infra/pages/chat/channel_list.dart'; +import 'package:dtim/infra/router/pop_router.dart'; +import 'package:flutter/material.dart'; +import 'package:expandable/expandable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:dtim/application/store/app/webrtc.dart'; +import 'package:dtim/domain/utils/screen/screen.dart'; +import 'package:dtim/infra/components/components.dart'; +import 'package:dtim/infra/components/popup.dart'; +import 'package:dtim/domain/models/models.dart'; +import 'package:dtim/application/store/app/app.dart'; +import 'package:dtim/application/store/theme.dart'; +// import 'package:dtim/domain/utils/webrtc/action.dart'; +import 'chat_menu.dart'; + +class OrgViewPage extends StatefulWidget { + final double width; + const OrgViewPage({super.key, required this.width}); + + @override + State createState() => _OrgViewPageState(); +} + +class _OrgViewPageState extends State { + late ExpandableController _controllerChannels; + late ExpandableController _controllerUsers; + + final BasePopupMenuController menuController = BasePopupMenuController(); + final StreamController menuStreamController = StreamController(); + late AppCubit im; + late AccountOrg org; + bool showType = false; + + @override + void initState() { + super.initState(); + _controllerChannels = ExpandableController(initialExpanded: true); + _controllerUsers = ExpandableController(initialExpanded: true); + menuController.addListener(() { + menuStreamController.add(menuController.menuIsShowing); + }); + + im = context.read(); + org = im.currentState!.org; + } + + @override + void dispose() { + super.dispose(); + _controllerChannels.dispose(); + _controllerUsers.dispose(); + } + + @override + Widget build(BuildContext context) { + final constTheme = Theme.of(context).extension()!; + + return Column( + children: [ + // moveWindow( + // Row( + // children: [ + // SizedBox(width: 14.w), + // BasePopupMenu( + // verticalMargin: -1.w, + // horizontalMargin: 5.w, + // showArrow: false, + // controller: menuController, + // pressType: PressType.singleClick, + // position: PreferredPosition.bottomLeft, + // child: StreamBuilder( + // stream: menuStreamController.stream, + // initialData: false, + // builder: (BuildContext context, AsyncSnapshot snapshot) { + // final imc = context.watch(); + // return Container( + // height: 35.w, + // width: widget.width - 79.w, + // padding: EdgeInsets.only(left: 10.w, right: 7.w, top: 2.w, bottom: 2.w), + // decoration: BoxDecoration( + // color: snapshot.data != null && snapshot.data! + // ? constTheme.centerChannelColor.withOpacity(0.25) + // : constTheme.centerChannelColor.withOpacity(0.1), + // borderRadius: BorderRadius.all(Radius.circular(3.w)), + // ), + // child: Row( + // children: [ + // Expanded( + // child: Text( + // imc.currentState!.org.nodeName ?? "", + // softWrap: true, + // overflow: TextOverflow.ellipsis, + // style: TextStyle( + // color: constTheme.centerChannelColor, + // fontWeight: FontWeight.w800, + // fontSize: 15.w, + // height: 1.3, + // ), + // ), + // ), + // Icon( + // Icons.keyboard_arrow_down_outlined, + // color: constTheme.centerChannelColor, + // size: 18.w, + // ), + // ], + // ), + // ); + // }, + // ), + // menuBuilder: () => orgMenuRender(menuController, widget.width - 30.w, im), + // ), + // SizedBox(width: 10.w), + // InkWell( + // onTap: () { + // var w = 0.8.sw > 700.w ? 700.w : 0.8.sw; + // showModelOrPage(context, "/search", width: w, top: 5.w); + // }, + // child: Container( + // height: 35.w, + // width: 35.w, + // margin: EdgeInsets.only(left: 0.w, right: 15.w, top: 15.w, bottom: 15.w), + // // padding: EdgeInsets.only(left: 10.w), + // decoration: BoxDecoration( + // color: constTheme.centerChannelColor.withOpacity(0.1), + // borderRadius: BorderRadius.all(Radius.circular(3.w)), + // ), + // alignment: Alignment.center, + // child: Icon(AppIcons.search, size: 16.w, color: constTheme.centerChannelColor), + // ), + // ), + // ], + // ), + // ), + // Divider( + // height: 1, + // color: constTheme.centerChannelColor.withOpacity(0.08), + // ), + SingleChildScrollView( + child: showType + ? Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + L10n.of(context)!.channel, + style: TextStyle( + color: constTheme.centerChannelColor, + fontWeight: FontWeight.w800, + fontSize: 14.w, + ), + ), + ), + Row( + children: [ + GestureDetector( + key: const Key("create_channel"), + onTap: () async { + showModelOrPage( + context, + "/create_channel", + width: 450.w, + height: 300.w, + ); + }, + child: Icon( + Icons.add, + size: 20.w, + color: constTheme.centerChannelColor, + ), + ), + SizedBox(width: 5.w), + GestureDetector( + onTap: () { + setState(() { + _controllerChannels.toggle(); + }); + }, + child: Icon( + _controllerChannels.expanded + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_up_outlined, + size: 25.w, + color: constTheme.centerChannelColor.withAlpha(180), + ), + ), + ], + ) + ], + ), + ), + ExpandablePanel( + key: const Key("room"), + controller: _controllerChannels, + collapsed: const SizedBox(), + expanded: const ChannelList(key: Key("ChannelList")), + ), + SizedBox(height: 5.w), + Divider( + height: 1, + color: constTheme.centerChannelColor.withOpacity(0.05), + ), + Padding( + padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + L10n.of(context)!.directChat, + style: TextStyle( + fontWeight: FontWeight.w800, + fontSize: 14.w, + color: constTheme.centerChannelColor, + ), + ), + ), + Row( + children: [ + GestureDetector( + key: const Key("create_private"), + onTap: () async { + var w = 0.8.sw > 700.w ? 700.w : 0.8.sw; + showModelOrPage( + context, + "/create_private", + width: w, + top: 5.w, + height: 0.7.sh, + ); + }, + child: Icon( + Icons.add, + size: 20.w, + color: constTheme.centerChannelColor, + ), + ), + SizedBox(width: 5.w), + GestureDetector( + onTap: () { + setState(() { + _controllerUsers.toggle(); + }); + }, + child: Icon( + _controllerUsers.expanded + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_up_outlined, + size: 25.w, + color: constTheme.centerChannelColor, + ), + ), + ], + ), + ], + ), + ), + ExpandablePanel( + key: const Key("droom"), + controller: _controllerUsers, + collapsed: const SizedBox(), + expanded: const DirectChats(key: Key("DirectChats")), + ), + SizedBox(height: 5.w), + Divider( + height: 1, + color: constTheme.centerChannelColor.withOpacity(0.05), + ), + BlocBuilder(builder: (context, state) { + final voip = im.currentState!.webrtcTool!.voip; + print("voip.calls.length: ${voip.calls.length}"); + print("voip.calls: ${voip.calls.toString()}"); + print("voip.groupCalls: ${voip.groupCalls.toString()}"); + List calls = []; + + if (voip.calls.isNotEmpty || voip.groupCalls.isNotEmpty) { + calls.add(Padding( + // decoration: BoxDecoration( + // border: Border(bottom: BorderSide(color: constTheme.centerChannelColor.withOpacity(0.1))), + // ), + padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + L10n.of(context)!.mediaChats, + style: TextStyle( + fontWeight: FontWeight.w800, + fontSize: 14.w, + color: constTheme.centerChannelColor, + ), + ), + ), + ], + ), + )); + } + + for (var k in voip.calls.keys) { + final call = voip.calls[k]!; + if (call.isGroupCall) continue; + calls.add( + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: constTheme.sidebarBg, + surfaceTintColor: Colors.transparent, + shadowColor: Colors.transparent, + padding: EdgeInsets.zero, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + side: BorderSide.none, + ), + elevation: 0, + ), + onPressed: () { + im.currentState!.webrtcTool!.addCallingPopup(call.callId, call); + }, + child: Padding( + padding: EdgeInsets.only(left: 12.w, right: 0.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(width: 2.w), + Icon(Icons.headphones_rounded, size: 16.w, color: constTheme.centerChannelColor), + SizedBox(width: 7.w), + Expanded( + child: Text( + call.room.getLocalizedDisplayname(), + style: TextStyle( + fontSize: 14.w, + color: constTheme.centerChannelColor, + ), + ), + ), + IconButton( + onPressed: () => im.currentState!.webrtcTool!.addCallingPopup(call.callId, call), + tooltip: 'open window', + icon: Icon( + AppIcons.fangda, + size: 16.w, + color: constTheme.centerChannelColor, + ), + ), + ], + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // for (var i = 0; i < actions.length; i++) + // Container( + // decoration: BoxDecoration( + // borderRadius: BorderRadius.all(Radius.circular(8.w)), + // color: actions[i].backgroundColor), + // margin: EdgeInsets.only(right: i != actions.length - 1 ? 5.w : 0), + // child: IconButton( + // iconSize: 18.w, + // constraints: BoxConstraints( + // minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w), + // style: IconButton.styleFrom( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8.w), + // ), + // ), + // padding: EdgeInsets.zero, + // icon: actions[i].child, + // color: Colors.white, + // onPressed: () async { + // actions[i].onPressed(); + // }, + // ), + // ), + // ], + // ), + ), + ), + ); + } + + for (var k in voip.groupCalls.keys) { + final call = voip.groupCalls[k]!; + if (k.callId.contains(":")) continue; + // final callActions = CallAction(call); + // final actions = callActions.buildActionButtons(); + calls.add( + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: constTheme.sidebarBg, + surfaceTintColor: Colors.transparent, + shadowColor: Colors.transparent, + padding: EdgeInsets.zero, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + side: BorderSide.none, + ), + elevation: 0, + ), + onPressed: () { + final org = context.read(); + org.setChannelId("meeting||$k"); + }, + child: Padding( + padding: EdgeInsets.only(left: 12.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(width: 2.w), + Icon(AppIcons.meeting_board, size: 19.w, color: constTheme.centerChannelColor), + SizedBox(width: 7.w), + Expanded( + child: Text( + call.room.getLocalizedDisplayname(), + style: TextStyle( + fontSize: 14.w, + color: constTheme.centerChannelColor, + ), + ), + ), + IconButton( + onPressed: () { + // im.currentState!.webrtcTool!.addCallingPopup(call.callId, call) + }, + tooltip: 'open window', + icon: Icon( + AppIcons.fangda, + size: 16.w, + color: constTheme.centerChannelColor, + ), + ), + ], + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // for (var i = 0; i < actions.length; i++) + // Container( + // decoration: BoxDecoration( + // borderRadius: BorderRadius.all(Radius.circular(8.w)), + // color: actions[i].backgroundColor), + // margin: EdgeInsets.only(right: i != actions.length - 1 ? 5.w : 0), + // child: IconButton( + // iconSize: 18.w, + // constraints: BoxConstraints( + // minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w), + // style: IconButton.styleFrom( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8.w), + // ), + // ), + // padding: EdgeInsets.zero, + // icon: actions[i].child, + // color: Colors.white, + // onPressed: () async { + // actions[i].onPressed(); + // }, + // ), + // ), + // ], + // ), + ), + ), + ); + } + + return Column(children: calls); + }) + ], + ) + : Column( + children: [ + SizedBox(height: 20.w), + const ChannelList(key: Key("ChannelList")), + ], + ), + ), + ], + ); + } +} diff --git a/lib/infra/pages/org/create_org.dart b/lib/infra/pages/chat/create_chat.dart similarity index 100% rename from lib/infra/pages/org/create_org.dart rename to lib/infra/pages/chat/create_chat.dart diff --git a/lib/infra/pages/main_pc.dart b/lib/infra/pages/main_pc.dart index 50ba14c7..48ac3870 100644 --- a/lib/infra/pages/main_pc.dart +++ b/lib/infra/pages/main_pc.dart @@ -102,6 +102,16 @@ class _PCPageState extends State { @override Widget build(BuildContext context) { final constTheme = Theme.of(context).extension()!; + final iconbg = constTheme.sidebarText.withOpacity(0.08); + final iconbt = ButtonStyle( + backgroundColor: MaterialStateProperty.all(iconbg), + foregroundColor: MaterialStateProperty.all(constTheme.sidebarText), + // elevation: MaterialStateProperty.all(24), + elevation: MaterialStateProperty.all(0), + shape: MaterialStateProperty.all( + const CircleBorder(), + ), + ); return Scaffold( backgroundColor: Colors.transparent, body: AutoTabsRouter.pageView( @@ -125,30 +135,64 @@ class _PCPageState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ if (PlatformInfos.isMacOS) SizedBox(height: 20.w), - SizedBox(height: 6.w), + SizedBox(height: 16.w), // 用户 SizedBox( - width: 40.w, - height: 40.w, + width: 32.w, + height: 32.w, child: MePop( im.me!.address, im.me!.name ?? "-", mxContent: avatar, true, - 40.w, - bg: constTheme.sidebarText.withOpacity(0.1), + 32.w, + bg: iconbg, color: constTheme.sidebarText, ), ), - Container( - width: 6.w, - height: 4.w, - margin: EdgeInsets.only(top: 12.w, bottom: 10.w), - decoration: BoxDecoration( - color: constTheme.sidebarText, - borderRadius: BorderRadius.circular(2.w), + SizedBox(height: 13.w), + ElevatedButton( + onPressed: () { + printDebug("discover and join"); + context.router.pushNamed("/select_org?t=back").then((value) { + getData(); + }); + }, + style: iconbt, + child: SizedBox( + width: 32.w, + height: 32.w, + child: Center( + child: Icon( + AppIcons.search, + size: 18.w, + color: constTheme.sidebarText, + ), + ), + ), + ), + SizedBox(height: 13.w), + ElevatedButton( + onPressed: () { + printDebug("discover and join"); + context.router.pushNamed("/select_org?t=back").then((value) { + getData(); + }); + }, + style: iconbt, + child: SizedBox( + width: 32.w, + height: 32.w, + child: Center( + child: Icon( + Icons.add, + size: 18.w, + color: constTheme.sidebarText, + ), + ), ), ), + SizedBox(height: 13.w), Flexible( child: StreamBuilder( stream: currentId.stream, @@ -160,6 +204,7 @@ class _PCPageState extends State { icon: AppIcons.chat, key: const Key("Chat"), selected: id.data == 0, + bg: iconbg, onTap: () { pageRouter.setActiveIndex(0); onSelect(0); @@ -171,6 +216,7 @@ class _PCPageState extends State { img: app.icon, key: Key("app_${app.hash}"), selected: id.data == app.appId! + 1, + bg: iconbg, onTap: () { if (app.appId! < 2) { pageRouter.setActiveIndex(app.appId! + 1); @@ -179,16 +225,16 @@ class _PCPageState extends State { }, ), // DAO管理 - SiderBarItem( - "Apps", - icon: AppIcons.shujujicheng, - key: const Key("Integrate"), - selected: id.data == 3, - onTap: () { - pageRouter.setActiveIndex(3); - onSelect(3); - }, - ), + // SiderBarItem( + // "Apps", + // icon: AppIcons.shujujicheng, + // key: const Key("Integrate"), + // selected: id.data == 3, + // onTap: () { + // pageRouter.setActiveIndex(3); + // onSelect(3); + // }, + // ), // DAO管理 // SiderBarItem( // "Dapps", @@ -205,35 +251,35 @@ class _PCPageState extends State { }, ), ), - IconButton( - tooltip: "discover and join", - onPressed: () { - printDebug("discover and join"); - context.router.pushNamed("/select_org?t=back").then((value) { - getData(); - }); - }, - icon: SizedBox( - width: 36.w, - height: 36.w, - child: Center( - child: Icon( - AppIcons.discoverfill, - size: 23.w, - color: constTheme.sidebarText, - ), - ), - ), - ), - Container( - width: 6.w, - height: 4.w, - margin: EdgeInsets.only(top: 0.w, bottom: 5.w), - decoration: BoxDecoration( - color: constTheme.sidebarText, - borderRadius: BorderRadius.circular(2.w), - ), - ), + // IconButton( + // tooltip: "discover and join", + // onPressed: () { + // printDebug("discover and join"); + // context.router.pushNamed("/select_org?t=back").then((value) { + // getData(); + // }); + // }, + // icon: SizedBox( + // width: 36.w, + // height: 36.w, + // child: Center( + // child: Icon( + // AppIcons.discoverfill, + // size: 23.w, + // color: constTheme.sidebarText, + // ), + // ), + // ), + // ), + // Container( + // width: 6.w, + // height: 4.w, + // margin: EdgeInsets.only(top: 0.w, bottom: 5.w), + // decoration: BoxDecoration( + // color: constTheme.sidebarText, + // borderRadius: BorderRadius.circular(2.w), + // ), + // ), if (aorgs != null) for (var i = 0; i < aorgs!.length; i++) GestureDetector( @@ -334,7 +380,7 @@ class _PCPageState extends State { ), ), ), - SizedBox(height: 15.w), + SizedBox(height: 10.w), ], ), ), diff --git a/lib/infra/pages/org/org_view.dart b/lib/infra/pages/org/org_view.dart deleted file mode 100644 index ed1da595..00000000 --- a/lib/infra/pages/org/org_view.dart +++ /dev/null @@ -1,480 +0,0 @@ -import 'dart:async'; -import 'package:dtim/application/store/app/org.dart'; -import 'package:dtim/infra/router/pop_router.dart'; -import 'package:flutter/material.dart'; -import 'package:expandable/expandable.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; - -import 'package:dtim/application/store/app/webrtc.dart'; -import 'package:dtim/domain/utils/screen/screen.dart'; -import 'package:dtim/infra/components/components.dart'; -import 'package:dtim/infra/components/popup.dart'; -import 'package:dtim/domain/models/models.dart'; -import 'package:dtim/application/store/app/app.dart'; -import 'package:dtim/application/store/theme.dart'; -// import 'package:dtim/domain/utils/webrtc/action.dart'; -import 'org_menu.dart'; - -class OrgViewPage extends StatefulWidget { - final double width; - const OrgViewPage({Key? key, required this.width}) : super(key: key); - - @override - State createState() => _OrgViewPageState(); -} - -class _OrgViewPageState extends State { - late ExpandableController _controllerChannels; - late ExpandableController _controllerUsers; - - final BasePopupMenuController menuController = BasePopupMenuController(); - final StreamController menuStreamController = StreamController(); - late AppCubit im; - late AccountOrg org; - - @override - void initState() { - super.initState(); - _controllerChannels = ExpandableController(initialExpanded: true); - _controllerUsers = ExpandableController(initialExpanded: true); - menuController.addListener(() { - menuStreamController.add(menuController.menuIsShowing); - }); - - im = context.read(); - org = im.currentState!.org; - } - - @override - void dispose() { - super.dispose(); - _controllerChannels.dispose(); - _controllerUsers.dispose(); - } - - @override - Widget build(BuildContext context) { - final constTheme = Theme.of(context).extension()!; - - return Column( - children: [ - moveWindow( - Row( - children: [ - SizedBox(width: 14.w), - BasePopupMenu( - verticalMargin: -1.w, - horizontalMargin: 5.w, - showArrow: false, - controller: menuController, - pressType: PressType.singleClick, - position: PreferredPosition.bottomLeft, - child: StreamBuilder( - stream: menuStreamController.stream, - initialData: false, - builder: (BuildContext context, AsyncSnapshot snapshot) { - final imc = context.watch(); - return Container( - height: 35.w, - width: widget.width - 79.w, - padding: EdgeInsets.only(left: 10.w, right: 7.w, top: 2.w, bottom: 2.w), - decoration: BoxDecoration( - color: snapshot.data != null && snapshot.data! - ? constTheme.sidebarText.withOpacity(0.25) - : constTheme.sidebarText.withOpacity(0.1), - borderRadius: BorderRadius.all(Radius.circular(3.w)), - ), - child: Row( - children: [ - Expanded( - child: Text( - imc.currentState!.org.nodeName ?? "", - softWrap: true, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: constTheme.sidebarText, - fontWeight: FontWeight.w800, - fontSize: 15.w, - height: 1.3, - ), - ), - ), - Icon( - Icons.keyboard_arrow_down_outlined, - color: constTheme.sidebarText, - size: 18.w, - ), - ], - ), - ); - }, - ), - menuBuilder: () => orgMenuRender(menuController, widget.width - 30.w, im), - ), - SizedBox(width: 10.w), - InkWell( - onTap: () { - var w = 0.8.sw > 700.w ? 700.w : 0.8.sw; - showModelOrPage(context, "/search", width: w, top: 5.w); - }, - child: Container( - height: 35.w, - width: 35.w, - margin: EdgeInsets.only(left: 0.w, right: 15.w, top: 15.w, bottom: 15.w), - // padding: EdgeInsets.only(left: 10.w), - decoration: BoxDecoration( - color: constTheme.sidebarText.withOpacity(0.1), - borderRadius: BorderRadius.all(Radius.circular(3.w)), - ), - alignment: Alignment.center, - child: Icon(AppIcons.search, size: 16.w, color: constTheme.sidebarText), - ), - ), - ], - ), - ), - Divider( - height: 1, - color: constTheme.sidebarText.withOpacity(0.08), - ), - Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - Padding( - padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - L10n.of(context)!.channel, - style: TextStyle( - color: constTheme.sidebarText, - fontWeight: FontWeight.w800, - fontSize: 14.w, - ), - ), - ), - Row( - children: [ - GestureDetector( - key: const Key("create_channel"), - onTap: () async { - showModelOrPage( - context, - "/create_channel", - width: 450.w, - height: 300.w, - ); - }, - child: Icon( - Icons.add, - size: 20.w, - color: constTheme.sidebarText, - ), - ), - SizedBox(width: 5.w), - GestureDetector( - onTap: () { - setState(() { - _controllerChannels.toggle(); - }); - }, - child: Icon( - _controllerChannels.expanded - ? Icons.keyboard_arrow_down_outlined - : Icons.keyboard_arrow_up_outlined, - size: 25.w, - color: constTheme.sidebarText.withAlpha(180), - ), - ), - ], - ) - ], - ), - ), - ExpandablePanel( - key: const Key("room"), - controller: _controllerChannels, - collapsed: const SizedBox(), - expanded: const ChannelList(key: Key("ChannelList")), - ), - SizedBox(height: 5.w), - Divider( - height: 1, - color: constTheme.sidebarText.withOpacity(0.05), - ), - Padding( - padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - L10n.of(context)!.directChat, - style: TextStyle( - fontWeight: FontWeight.w800, - fontSize: 14.w, - color: constTheme.sidebarText, - ), - ), - ), - Row( - children: [ - GestureDetector( - key: const Key("create_private"), - onTap: () async { - var w = 0.8.sw > 700.w ? 700.w : 0.8.sw; - showModelOrPage( - context, - "/create_private", - width: w, - top: 5.w, - height: 0.7.sh, - ); - }, - child: Icon( - Icons.add, - size: 20.w, - color: constTheme.sidebarText, - ), - ), - SizedBox(width: 5.w), - GestureDetector( - onTap: () { - setState(() { - _controllerUsers.toggle(); - }); - }, - child: Icon( - _controllerUsers.expanded - ? Icons.keyboard_arrow_down_outlined - : Icons.keyboard_arrow_up_outlined, - size: 25.w, - color: constTheme.sidebarText, - ), - ), - ], - ), - ], - ), - ), - ExpandablePanel( - key: const Key("droom"), - controller: _controllerUsers, - collapsed: const SizedBox(), - expanded: const DirectChats(key: Key("DirectChats")), - ), - SizedBox(height: 5.w), - Divider( - height: 1, - color: constTheme.sidebarText.withOpacity(0.05), - ), - BlocBuilder(builder: (context, state) { - final voip = im.currentState!.webrtcTool!.voip; - print("voip.calls.length: ${voip.calls.length}"); - print("voip.calls: ${voip.calls.toString()}"); - print("voip.groupCalls: ${voip.groupCalls.toString()}"); - List calls = []; - - if (voip.calls.isNotEmpty || voip.groupCalls.isNotEmpty) { - calls.add(Padding( - // decoration: BoxDecoration( - // border: Border(bottom: BorderSide(color: constTheme.sidebarText.withOpacity(0.1))), - // ), - padding: EdgeInsets.only(left: 15.w, right: 8.w, top: 10.w, bottom: 5.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - L10n.of(context)!.mediaChats, - style: TextStyle( - fontWeight: FontWeight.w800, - fontSize: 14.w, - color: constTheme.sidebarText, - ), - ), - ), - ], - ), - )); - } - - for (var k in voip.calls.keys) { - final call = voip.calls[k]!; - if (call.isGroupCall) continue; - calls.add( - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: constTheme.sidebarBg, - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - padding: EdgeInsets.zero, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.zero, - side: BorderSide.none, - ), - elevation: 0, - ), - onPressed: () { - im.currentState!.webrtcTool!.addCallingPopup(call.callId, call); - }, - child: Padding( - padding: EdgeInsets.only(left: 12.w, right: 0.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox(width: 2.w), - Icon(Icons.headphones_rounded, size: 16.w, color: constTheme.sidebarText), - SizedBox(width: 7.w), - Expanded( - child: Text( - call.room.getLocalizedDisplayname(), - style: TextStyle( - fontSize: 14.w, - color: constTheme.sidebarText, - ), - ), - ), - IconButton( - onPressed: () => im.currentState!.webrtcTool!.addCallingPopup(call.callId, call), - tooltip: 'open window', - icon: Icon( - AppIcons.fangda, - size: 16.w, - color: constTheme.sidebarText, - ), - ), - ], - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // for (var i = 0; i < actions.length; i++) - // Container( - // decoration: BoxDecoration( - // borderRadius: BorderRadius.all(Radius.circular(8.w)), - // color: actions[i].backgroundColor), - // margin: EdgeInsets.only(right: i != actions.length - 1 ? 5.w : 0), - // child: IconButton( - // iconSize: 18.w, - // constraints: BoxConstraints( - // minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w), - // style: IconButton.styleFrom( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8.w), - // ), - // ), - // padding: EdgeInsets.zero, - // icon: actions[i].child, - // color: Colors.white, - // onPressed: () async { - // actions[i].onPressed(); - // }, - // ), - // ), - // ], - // ), - ), - ), - ); - } - - for (var k in voip.groupCalls.keys) { - final call = voip.groupCalls[k]!; - if (k.callId.contains(":")) continue; - // final callActions = CallAction(call); - // final actions = callActions.buildActionButtons(); - calls.add( - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: constTheme.sidebarBg, - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - padding: EdgeInsets.zero, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.zero, - side: BorderSide.none, - ), - elevation: 0, - ), - onPressed: () { - final org = context.read(); - org.setChannelId("meeting||$k"); - }, - child: Padding( - padding: EdgeInsets.only(left: 12.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox(width: 2.w), - Icon(AppIcons.meeting_board, size: 19.w, color: constTheme.sidebarText), - SizedBox(width: 7.w), - Expanded( - child: Text( - call.room.getLocalizedDisplayname(), - style: TextStyle( - fontSize: 14.w, - color: constTheme.sidebarText, - ), - ), - ), - IconButton( - onPressed: () { - // im.currentState!.webrtcTool!.addCallingPopup(call.callId, call) - }, - tooltip: 'open window', - icon: Icon( - AppIcons.fangda, - size: 16.w, - color: constTheme.sidebarText, - ), - ), - ], - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // for (var i = 0; i < actions.length; i++) - // Container( - // decoration: BoxDecoration( - // borderRadius: BorderRadius.all(Radius.circular(8.w)), - // color: actions[i].backgroundColor), - // margin: EdgeInsets.only(right: i != actions.length - 1 ? 5.w : 0), - // child: IconButton( - // iconSize: 18.w, - // constraints: BoxConstraints( - // minWidth: 30.w, maxWidth: 30.w, minHeight: 30.w, maxHeight: 30.w), - // style: IconButton.styleFrom( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8.w), - // ), - // ), - // padding: EdgeInsets.zero, - // icon: actions[i].child, - // color: Colors.white, - // onPressed: () async { - // actions[i].onPressed(); - // }, - // ), - // ), - // ], - // ), - ), - ), - ); - } - - return Column(children: calls); - }) - ], - ), - ), - ), - ], - ); - } -} diff --git a/lib/infra/router/pop_router.dart b/lib/infra/router/pop_router.dart index 9f600bec..ab5695da 100644 --- a/lib/infra/router/pop_router.dart +++ b/lib/infra/router/pop_router.dart @@ -4,10 +4,10 @@ import 'package:dtim/infra/pages/user/kyc.dart'; import 'package:dtim/infra/pages/user/setting.dart'; import 'package:flutter/material.dart'; -import 'package:dtim/infra/pages/channel/create_private.dart'; -import 'package:dtim/infra/pages/channel/setting/setting.dart'; +import 'package:dtim/infra/pages/chat/channel/create_private.dart'; +import 'package:dtim/infra/pages/chat/channel/setting/setting.dart'; import 'package:dtim/infra/pages/setting/setting.dart'; -import 'package:dtim/infra/pages/channel/create.dart'; +import 'package:dtim/infra/pages/chat/channel/create.dart'; import 'package:dtim/infra/pages/search.dart'; import 'package:dtim/domain/utils/platform_infos.dart'; import 'package:dtim/domain/utils/screen/screen.dart'; @@ -82,8 +82,8 @@ Future showModelOrPage(context, url, {double width = 520, double height = context: context, useSafeArea: true, barrierColor: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.7), + ? Colors.black.withOpacity(0.85) + : Colors.white.withOpacity(0.85), builder: (context) { final media = MediaQuery.of(context); final bottom = media.size.height - 30.w - height.w; @@ -107,7 +107,6 @@ Future showModelOrPage(context, url, {double width = 520, double height = ], ), child: ClipRRect( - // clipBehavior: Clip.hardEdge, borderRadius: BorderRadius.circular( 7.w, ), diff --git a/lib/infra/router/router.dart b/lib/infra/router/router.dart index 706daffd..eac3217c 100644 --- a/lib/infra/router/router.dart +++ b/lib/infra/router/router.dart @@ -1,10 +1,10 @@ import 'package:dtim/domain/utils/platform_infos.dart'; import 'package:dtim/infra/pages/main_mobile.dart'; -import 'package:dtim/infra/pages/org/org_mobile.dart'; +import 'package:dtim/infra/pages/chat/chat_mobile.dart'; import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import 'package:dtim/infra/pages/integrate/integrate.dart'; -import 'package:dtim/infra/pages/org/create_org.dart'; +import 'package:dtim/infra/pages/chat/create_chat.dart'; import 'package:dtim/infra/pages/webview/webview.dart'; import 'package:dtim/infra/pages/chain/import_sr25519_key.dart'; @@ -12,7 +12,7 @@ import 'package:dtim/infra/pages/chain/sr25519_key.dart'; import 'package:dtim/infra/pages/main_pc.dart'; import 'package:dtim/infra/pages/select_org.dart'; import 'package:dtim/application/store/app/app.dart'; -import 'package:dtim/infra/pages/org/org.dart'; +import 'package:dtim/infra/pages/chat/chat.dart'; import 'package:dtim/infra/pages/preloader.dart'; part 'router.gr.dart'; diff --git a/lib/main.dart b/lib/main.dart index b65eaefb..a7eb2e07 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -113,10 +113,12 @@ class App extends StatelessWidget { theme: light, builder: (context, child) { final MediaQueryData data = MediaQuery.of(context); + if (isPc()) { + child = virtualAeroFrameBuilder(context, child); + } child = botToastBuilder(context, child); ScreenUtil.setConText(context); - child = virtualAeroFrameBuilder(context, child); - + return MediaQuery( data: data.copyWith(textScaler: const TextScaler.linear(1)), child: child,