Пример #1
0
 // Build the animation for the overall draggable dismissable content.
 Widget _buildAnimation(BuildContext context, Widget child)
 {
     return(Transform.translate(
                offset: _moveAnimation.value,
                child: child
                ));
 }
Пример #2
0
 public override Widget buildTransitions(BuildContext context1, Animation <float> animation, Animation <float> secondaryAnimation, Widget child)
 {
     return(new OrientationBuilder(
                builder: (BuildContext context2, Orientation orientation) => {
         _lastOrientation = orientation;
         if (!animation.isCompleted)
         {
             bool reverse = animation.status == AnimationStatus.reverse;
             Rect rect = reverse
                     ? _rectAnimatableReverse.evaluate(animation)
                     : _rectAnimatable.evaluate(animation);
             Rect sheetRect = reverse
                     ? _sheetRectAnimatableReverse.evaluate(animation)
                     : _sheetRectAnimatable.evaluate(animation);
             float?sheetScale = reverse
                     ? _sheetScaleAnimatableReverse.evaluate(animation)
                     : _sheetScaleAnimatable.evaluate(animation);
             List <Widget> widgets = new List <Widget>();
             widgets.Add(
                 Positioned.fromRect(
                     rect: sheetRect,
                     child: new Opacity(
                         opacity: _sheetOpacity.value,
                         child: Transform.scale(
                             alignment: getSheetAlignment(_contextMenuLocation),
                             scale: sheetScale ?? 1.0f,
                             child: new _ContextMenuSheet(
                                 key: _sheetGlobalKey,
                                 actions: _actions,
                                 contextMenuLocation: _contextMenuLocation,
                                 orientation: orientation
                                 )
                             )
                         )
                     )
                 );
             widgets.Add(
                 Positioned.fromRect(
                     key: _childGlobalKey,
                     rect: rect,
                     child: _builder(context2, animation)
                     ));
             return new Stack(
                 children: widgets
                 );
         }
         return new _ContextMenuRouteStatic(
             actions: _actions,
             child: _builder(context1, animation),
             childGlobalKey: _childGlobalKey,
             contextMenuLocation: _contextMenuLocation,
             onDismiss: _onDismiss,
             orientation: orientation,
             sheetGlobalKey: _sheetGlobalKey
             );
     }
                ));
 }
Пример #3
0
            public override Widget build(BuildContext context)
            {
                Widget child = new Container(
                    decoration: new BoxDecoration(
                        boxShadow: new List <BoxShadow>
                {
                    new BoxShadow(
                        color: new Color(0x66000000),
                        offset: new Offset(0, 2f),
                        blurRadius: 4f
                        )
                },
                        borderRadius: BorderRadius.all(32),
                        color: new Color(0xff000000)
                        ),
                    height: 64,
                    width: 64,
                    child: new Center(
                        child: Transform.rotate(
                            degree: Mathf.PI,
                            alignment: Alignment.center,
                            child: new Icon(
                                Icons.MaterialExpandMore,
                                color: new Color(0xffffffff),
                                size: 32f
                                )
                            )
                        )
                    );

                if (widget._displayThreshold != null)
                {
                    if (Math.Abs(_animation.value) < 1e-2)
                    {
                        child = null;
                    }
                    else
                    {
                        child = new Opacity(
                            opacity: _animation.value,
                            child: child
                            );
                    }
                }

                return(new Positioned(
                           bottom: 140,
                           right: 48,
                           child: new Clickable(
                               onTap: () => widget._scrollController.animateTo(
                                   0,
                                   SuitableAnimationTimeSpan,
                                   Curves.easeIn),
                               child: child
                               )
                           ));
            }
Пример #4
0
        public override Widget build(int i, float animationValue, Widget widget)
        {
            Offset s = CustomLayoutUtils._getOffsetValue(values: this.values, animationValue: animationValue, index: i);

            return(Transform.translate(
                       offset: s,
                       child: widget
                       ));
        }
Пример #5
0
        public override Widget build(int i, float animationValue, Widget widget)
        {
            float v = CustomLayoutUtils._getValue(values: this.values, animationValue: animationValue, index: i);

            return(Transform.rotate(
                       degree: v,
                       child: widget
                       ));
        }
Пример #6
0
 // Build the animation for the _ContextMenuSheet.
 Widget _buildSheetAnimation(BuildContext context, Widget child)
 {
     return(Transform.scale(
                alignment: _ContextMenuRoute.getSheetAlignment(widget.contextMenuLocation),
                scale: _sheetScaleAnimation.value,
                child: new Opacity(
                    opacity: _sheetOpacityAnimation.value,
                    child: child
                    )
                ));
 }
Пример #7
0
 public override Widget build(BuildContext context)
 {
     return(Transform.rotate(
                degree: _animation.value,
                alignment: Alignment.center,
                child: new Icon(
                    Icons.IconFontLoading,
                    size: widget._size,
                    color: IconColor
                    )
                ));
 }
Пример #8
0
 // Build the animation for the child.
 Widget _buildChildAnimation(BuildContext context, Widget child)
 {
     _lastScale = _getScale(
         widget.orientation,
         MediaQuery.of(context).size.height,
         _moveAnimation.value.dy
         );
     return(Transform.scale(
                key: widget.childGlobalKey,
                scale: _lastScale,
                child: child
                ));
 }
Пример #9
0
 public override Widget build(BuildContext context)
 {
     return(Transform.rotate(
                degree: m_Animation.value,
                alignment: Alignment.center,
                child: new Container(
                    width: widget.size,
                    height: widget.size,
                    child: Image.asset(
                        widget.isWhite ? "Images/white-loading" : "Images/black-loading"
                        )
                    )
                ));
 }
Пример #10
0
 public override Widget build(BuildContext context)
 {
     return(SizedBox.fromSize(size: AppConstants.DIRECTION_BUTTON_SIZE * 2.8f,
                              child: Transform.rotate(
                                  origin: new Offset(90, 90),
                                  degree: Mathf.PI / 4,
                                  child: new Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: new List <Widget>()
     {
         new SizedBox(height: AppConstants.DIRECTION_BUTTON_SPACE),
         new Row(
             children: new List <Widget>()
         {
             new SizedBox(width: AppConstants.DIRECTION_BUTTON_SPACE),
             new GBButton(
                 size: AppConstants.DIRECTION_BUTTON_SIZE,
                 () => { Game.of(context).Drop(); }
                 ),
             new SizedBox(width: AppConstants.DIRECTION_BUTTON_SPACE),
             new GBButton(
                 size: AppConstants.DIRECTION_BUTTON_SIZE,
                 () => { Game.of(context).Right(); }
                 )
         }
             ),
         new SizedBox(height: AppConstants.DIRECTION_BUTTON_SPACE),
         new Row(
             children: new List <Widget>()
         {
             new SizedBox(width: AppConstants.DIRECTION_BUTTON_SPACE),
             new GBButton(
                 size: AppConstants.DIRECTION_BUTTON_SIZE,
                 () => { Game.of(context).Left(); }
                 ),
             new SizedBox(width: AppConstants.DIRECTION_BUTTON_SPACE),
             new GBButton(
                 size: AppConstants.DIRECTION_BUTTON_SIZE,
                 () => { Game.of(context).Down(); }
                 )
         }
             ),
         new SizedBox(height: AppConstants.DIRECTION_BUTTON_SPACE)
     }
                                      )
                                  )
                              ));
 }
Пример #11
0
        public override Widget build(BuildContext context)
        {
            D.assert(WidgetsD.debugCheckHasDirectionality(context));
            D.assert(material_.debugCheckHasMaterialLocalizations(context));
            D.assert(material_.debugCheckHasMaterialLocalizations(context));

            ThemeData     theme    = Theme.of(context);
            List <Widget> children = new List <Widget> {
            };

            if (widget.accountName != null)
            {
                Widget accountNameLine = new LayoutId(
                    id: _AccountDetailsLayout.accountName,
                    child: new Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0f),
                        child: new DefaultTextStyle(
                            style: theme.primaryTextTheme.bodyText1,
                            overflow: TextOverflow.ellipsis,
                            child: widget.accountName
                            )
                        )
                    );
                children.Add(accountNameLine);
            }

            if (widget.accountEmail != null)
            {
                Widget accountEmailLine = new LayoutId(
                    id: _AccountDetailsLayout.accountEmail,
                    child: new Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0f),
                        child: new DefaultTextStyle(
                            style: theme.primaryTextTheme.bodyText2,
                            overflow: TextOverflow.ellipsis,
                            child: widget.accountEmail
                            )
                        )
                    );
                children.Add(accountEmailLine);
            }

            if (widget.onTap != null)
            {
                Widget dropDownIcon = new LayoutId(
                    id: _AccountDetailsLayout.dropdownIcon,
                    child: new SizedBox(
                        height: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
                        width: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
                        child: new Center(
                            child: Transform.rotate(
                                angle: _animation.value * Mathf.PI,
                                child: new Icon(
                                    Icons.arrow_drop_down,
                                    color: widget.arrowColor
                                    )
                                )
                            )
                        )
                    );
                children.Add(dropDownIcon);
            }

            Widget accountDetails = new CustomMultiChildLayout(
                layoutDelegate: new _AccountDetailsLayout(
                    Directionality.of(context)),
                children: children
                );

            if (widget.onTap != null)
            {
                accountDetails = new InkWell(
                    onTap: widget.onTap == null ? (GestureTapCallback)null : () => { widget.onTap(); },
                    child: accountDetails
                    );
            }

            return(new SizedBox(
                       height: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
                       child: accountDetails
                       ));
        }
Пример #12
0
        public override Widget build(int i, float animationValue, Widget widget)
        {
            float s = CustomLayoutUtils._getValue(values: this.values, animationValue: animationValue, index: i);

            return(Transform.scale(scale: s, child: widget));
        }
        public override Widget build(BuildContext context)
        {
            return(new GestureDetector
                   (
                       onLongPressDragUpdate: details =>
            {
//                    Debug.Log("onLongPressDragUpdate");
            },
                       onScaleStart: details =>
            {
                MoveEndVelocity = Offset.zero;
                previousScrollPosition = details.focalPoint;
                previousDragPosition = details.focalPoint;
            },
                       onScaleUpdate: details =>
            {
//                    Debug.Log("onScaleUpdate");
                MoveEndVelocity = Offset.zero;
                float scaleDiff = previousScale * (details.scale - 1);
                if (aimedScale >= widget.MaxScale && scaleDiff > 0)
                {
                    scaleDiff = 0;
                }

                if (aimedScale <= widget.MinScale && scaleDiff < 0)
                {
                    scaleDiff = 0;
                }
                scroll(details.focalPoint, scaleDiff);
                move(details.focalPoint);
//                    postCheck();
            },
                       onScaleEnd: details =>
            {
                MoveEndVelocity = details.velocity.pixelsPerSecond;
            },
                       onVerticalDragStart: details =>
            {
                MoveEndVelocity = Offset.zero;
                previousScrollPosition = details.globalPosition;
                previousDragPosition = details.globalPosition;
            },
                       onVerticalDragUpdate: details =>
            {
//                    Debug.Log("onVerticalDragUpdate");
                if (details.isScroll)
                {
                    float scaleDiff = details.delta.dy / MediaQuery.of(context).size.height;
                    if (aimedScale >= widget.MaxScale && scaleDiff > 0)
                    {
                        scaleDiff = 0;
                    }
                    if (aimedScale <= widget.MinScale && scaleDiff < 0)
                    {
                        scaleDiff = 0;
                    }
                    if (Math.Abs(scaleDiff) > float.Epsilon)
                    {
                        scroll(details.globalPosition, scaleDiff);
                    }
//                        postCheck();
                }
                else
                {
                    move(details.globalPosition);
//                        postCheck();
                }
            },
                       onVerticalDragEnd: details =>
            {
                MoveEndVelocity = details.velocity.pixelsPerSecond;
            },
                       child: new ClipRect
                       (
                           clipBehavior: Clip.hardEdge,
                           child: new Stack
                           (
                               children: new List <Widget>
            {
                new Positioned
                (
                    left: Offset.dx,
                    top: Offset.dy,
                    child: Transform.scale
                    (
                        scale: Scale,
                        child: new Container(
                            key: ContentViewContainerKey,
                            width: widget.ContentSizeWidth,
                            height: widget.ContentSizeHeight,
                            child: widget.child
                            ),
                        alignment: Alignment.topLeft
                    )
                )
            }
                           )
                       )
                   ));
        }
Пример #14
0
        Widget _buildContent(BuildContext context)
        {
            var articleIds         = this.widget.viewModel.team.articleIds;
            var articlesHasMore    = this.widget.viewModel.team.articlesHasMore ?? false;
            var teamArticleLoading = this.widget.viewModel.teamArticleLoading && articleIds == null;
            int itemCount;

            if (teamArticleLoading)
            {
                itemCount = 3;
            }
            else
            {
                if (articleIds == null)
                {
                    itemCount = 3;
                }
                else
                {
                    var articleCount = articlesHasMore ? articleIds.Count : articleIds.Count + 1;
                    itemCount = 2 + (articleIds.Count == 0 ? 1 : articleCount);
                }
            }

            return(new Container(
                       color: CColors.Background,
                       child: new CustomScrollbar(
                           new SmartRefresher(
                               controller: this._refreshController,
                               enablePullDown: false,
                               enablePullUp: articlesHasMore,
                               onRefresh: this._onRefresh,
                               onNotification: this._onNotification,
                               child: ListView.builder(
                                   physics: new AlwaysScrollableScrollPhysics(),
                                   itemCount: itemCount,
                                   itemBuilder: (cxt, index) => {
                if (index == 0)
                {
                    return Transform.scale(
                        scale: this._factor,
                        child: this._buildTeamInfo()
                        );
                }

                if (index == 1)
                {
                    return _buildTeamArticleTitle();
                }

                if (teamArticleLoading && index == 2)
                {
                    var height = MediaQuery.of(context: context).size.height - headerHeight - 44;
                    return new Container(
                        height: height,
                        child: new GlobalLoading()
                        );
                }

                if ((articleIds == null || articleIds.Count == 0) && index == 2)
                {
                    var height = MediaQuery.of(context: context).size.height - headerHeight - 44;
                    return new Container(
                        height: height,
                        child: new BlankView(
                            "哎呀,暂无已发布的文章",
                            "image/default-article"
                            )
                        );
                }

                if (index == itemCount - 1 && !articlesHasMore)
                {
                    return new EndView();
                }

                var articleId = articleIds[index - 2];
                if (!this.widget.viewModel.articleDict.ContainsKey(key: articleId))
                {
                    return new Container();
                }

                var article = this.widget.viewModel.articleDict[key: articleId];
                return new ArticleCard(
                    article: article,
                    () => this.widget.actionModel.pushToArticleDetail(obj: article.id),
                    () => this._share(article: article),
                    fullName: this.widget.viewModel.team.name,
                    key: new ObjectKey(value: article.id)
                    );
            }
                                   )
                               )
                           )
                       ));
        }
Пример #15
0
        Widget _buildUserContent(BuildContext context)
        {
            var articleIds         = this.widget.viewModel.user.articleIds;
            var articlesHasMore    = this.widget.viewModel.user.articlesHasMore ?? false;
            var userArticleLoading = this.widget.viewModel.userArticleLoading && articleIds == null;
            int itemCount;

            if (userArticleLoading)
            {
                itemCount = 3;
            }
            else
            {
                if (articleIds == null)
                {
                    itemCount = 3;
                }
                else
                {
                    var articleCount = articlesHasMore ? articleIds.Count : articleIds.Count + 1;
                    itemCount = 2 + (articleIds.Count == 0 ? 1 : articleCount);
                }
            }

            return(new Container(
                       color: CColors.Background,
                       child: new CustomScrollbar(
                           new SmartRefresher(
                               controller: this._refreshController,
                               enablePullDown: false,
                               enablePullUp: articlesHasMore,
                               onRefresh: this._onRefresh,
                               onNotification: this._onNotification,
                               child: ListView.builder(
                                   physics: new AlwaysScrollableScrollPhysics(),
                                   itemCount: itemCount,
                                   itemBuilder: (cxt, index) => {
                if (index == 0)
                {
                    return Transform.scale(
                        scale: this._factor,
                        child: this._buildUserInfo()
                        );
                }

                if (index == 1)
                {
                    return _buildUserArticleTitle();
                }

                if (userArticleLoading && index == 2)
                {
                    var height = MediaQuery.of(context: context).size.height - headerHeight - 44;
                    return new Container(
                        height: height,
                        child: new GlobalLoading()
                        );
                }

                if ((articleIds == null || articleIds.Count == 0) && index == 2)
                {
                    var height = MediaQuery.of(context: context).size.height - headerHeight - 44;
                    return new Container(
                        height: height,
                        child: new BlankView(
                            "哎呀,暂无已发布的文章",
                            "image/default-article"
                            )
                        );
                }

                if (index == itemCount - 1 && !articlesHasMore)
                {
                    return new EndView();
                }

                var articleId = articleIds[index - 2];
                if (!this.widget.viewModel.articleDict.ContainsKey(key: articleId))
                {
                    return new Container();
                }

                var article = this.widget.viewModel.articleDict[key: articleId];
                var linkUrl = CStringUtils.JointProjectShareLink(projectId: article.id);
                return new ArticleCard(
                    article: article,
                    () => this.widget.actionModel.pushToArticleDetail(obj: article.id),
                    () => ShareManager.showArticleShareView(
                        this.widget.viewModel.currentUserId != article.userId,
                        isLoggedIn: this.widget.viewModel.isLoggedIn,
                        () => {
                    Clipboard.setData(new ClipboardData(text: linkUrl));
                    CustomDialogUtils.showToast("复制链接成功", Icons.check_circle_outline);
                },
                        () => this.widget.actionModel.pushToLogin(),
                        () => this.widget.actionModel.pushToBlock(article.id),
                        () => this.widget.actionModel.pushToReport(article.id, ReportType.article),
                        type => {
                    CustomDialogUtils.showCustomDialog(
                        child: new CustomLoadingDialog()
                        );
                    string imageUrl = CImageUtils.SizeTo200ImageUrl(article.thumbnail.url);
                    this.widget.actionModel.shareToWechat(arg1: type, arg2: article.title,
                                                          arg3: article.subTitle, arg4: linkUrl, arg5: imageUrl)
                    .Then(onResolved: CustomDialogUtils.hiddenCustomDialog)
                    .Catch(_ => CustomDialogUtils.hiddenCustomDialog());
                },
                        () => this.widget.actionModel.mainRouterPop()
                        ),
                    this.widget.viewModel.user.fullName ?? this.widget.viewModel.user.name,
                    key: new ObjectKey(value: article.id)
                    );
            }
                                   )
                               )
                           )
                       ));
        }
Пример #16
0
        public override Widget build(BuildContext context)
        {
            var screenSize   = MediaQuery.of(context).size;
            var screenWidth  = screenSize.width;
            var screenHeight = screenSize.height;

            var headerChildren = new List <Widget>
            {
                new Expanded(
                    child: new Text(
                        $"{channel?.name ?? string.Empty}",
                        style: new TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.w500,
                            color: new Color(0xff212121),
                            fontFamily: "PingFang"
                            )
                        )
                    ),
            };

            headerChildren.Add(
                new GestureDetector(
                    onTap: () =>
            {
                if (screenWidth < 750)
                {
                    m_AnimationController.reverse();
                }
                else
                {
                    HomePage.of(this.context).HideChannelInfo();
                }
            },
                    child: new Icon(
                        IconFont.IconFontClose,
                        color: new Color(0xff979a9e),
                        size: 28
                        )
                    )
                );

            var children = new List <Widget> {
            };

            if (channel == null)
            {
                children.Add(
                    new Loading(size: 56)
                    );
            }
            else
            {
                children.Add(
                    CreateLobbyIcon(
                        channel.thumbnail,
                        size: 184,
                        radius: 4
                        )
                    );
                children.Add(
                    new Container(
                        margin: EdgeInsets.only(top: 32),
                        child: new Text(
                            channel.name,
                            style: new TextStyle(
                                color: new Color(0xff000000),
                                fontSize: 24,
                                fontWeight: FontWeight.bold
                                )
                            )
                        )
                    );
                children.Add(
                    new Container(
                        margin: EdgeInsets.only(top: 8),
                        child: new Text(
                            $"{channel.memberCount}成员",
                            style: new TextStyle(
                                color: new Color(0xff797979),
                                fontSize: 14
                                )
                            )
                        )
                    );
                var topic = channel.topic;
                if (!channel.groupId.IsNullOrEmpty() && group != null)
                {
                    topic = group.description;
                }

                children.Add(
                    new Container(
                        margin: EdgeInsets.only(top: 32),
                        child: new Text(
                            topic,
                            style: new TextStyle(
                                color: new Color(0xff000000),
                                fontSize: 14
                                )
                            )
                        )
                    );
                var buttonChildren = new List <Widget>();
                if (m_Joining)
                {
                    buttonChildren.Add(
                        new Text(
                            "加入群聊",
                            style: new TextStyle(
                                color: new Color(0x00000000),
                                fontSize: 18,
                                fontFamily: "PingFang"
                                )
                            )
                        );
                    buttonChildren.Add(
                        new Loading(
                            size: 24
                            )
                        );
                }
                else
                {
                    buttonChildren.Add(
                        new Text(
                            "加入群聊",
                            style: new TextStyle(
                                fontSize: 18,
                                color: new Color(0xff2196f3),
                                fontFamily: "PingFang"
                                )
                            )
                        );
                }

                children.Add(
                    new GestureDetector(
                        onTap: () =>
                {
                    if (m_Joining)
                    {
                        return;
                    }
                    setState(() => m_Joining = true);
                    var requestUrl           = string.IsNullOrEmpty(channel.groupId)
                                ? $"/api/connectapp/v1/channels/{channel.id}/join"
                                : $"/api/connectapp/v1/groups/{channel.groupId}/join";
                    Utils.Post <JoinChannelResponse>(
                        requestUrl,
                        "{}"
                        ).Then(response =>
                    {
                        using (WindowProvider.of(context).getScope())
                        {
                            if (mounted)
                            {
                                var state           = HomePage.of(context);
                                var responseChannel = response.channel;
                                state.AddChannel(responseChannel);
                                state.Select(responseChannel.id);
                                state.Ack(responseChannel.id);
                                setState(() => m_Joining = false);
                            }
                        }
                    });
                },
                        child: new Container(
                            height: 56,
                            width: 234,
                            margin: EdgeInsets.only(top: 48),
                            decoration: new BoxDecoration(
                                color: new Color(0xffffffff),
                                borderRadius: BorderRadius.circular(6),
                                border: Border.all(
                                    color: new Color(0xff2196f3)
                                    )
                                ),
                            alignment: Alignment.center,
                            child: new Stack(
                                alignment: Alignment.center,
                                children: buttonChildren
                                )
                            )
                        )
                    );
            }

            Widget all = new Container(
                color: new Color(0xffffffff),
                child: new Scroller(
                    child: new SingleChildScrollView(
                        child: new Column(
                            children: new List <Widget>
            {
                new Container(
                    height: 64,
                    decoration: new BoxDecoration(
                        border: new Border(
                            bottom: new BorderSide(
                                color: new Color(0xffd8d8d8)
                                )
                            )
                        ),
                    padding: EdgeInsets.symmetric(horizontal: 24),
                    alignment: Alignment.center,
                    child: new Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: headerChildren
                        )
                    ),
                new Container(
                    constraints: new BoxConstraints(
                        minHeight: screenHeight - 64
                        ),
                    width: screenWidth < 750 ? (float?)null : 450,
                    margin: EdgeInsets.symmetric(horizontal: 24),
                    alignment: Alignment.center,
                    child: new Column(
                        children: children
                        )
                    ),
            }
                            )
                        )
                    )
                );

            var stacked = new List <Widget> {
                all
            };

            all = new Stack(
                children: stacked
                );

            if (screenWidth < 750)
            {
                all = Transform.translate(
                    offset: new Offset(0, (1 - m_AnimationController.value) * screenHeight),
                    child: all
                    );
            }

            return(all);
        }
Пример #17
0
        public override Widget build(BuildContext context)
        {
            var channel = widget.channels[widget.selectedChannelId];

            Widget members;

            var screenSize     = MediaQuery.of(context).size;
            var screenWidth    = screenSize.width;
            var screenHeight   = screenSize.height;
            var containerWidth = screenWidth - 48;

            if (screenWidth >= 750)
            {
                containerWidth -= 375;
            }

            var countPerRow = (containerWidth / 240).floor();
            var rowCount    = ((widget.members.ContainsKey(channel.id) ? widget.members[channel.id].Count : 0) /
                               (float)countPerRow).ceil();

            if (!widget.hasMoreMembers.ContainsKey(widget.selectedChannelId))
            {
                widget.hasMoreMembers[widget.selectedChannelId] = true;
            }
            if (widget.hasMoreMembers[widget.selectedChannelId])
            {
                rowCount += 1;
            }

            members = new SliverList(
                del: new SliverChildBuilderDelegate(
                    builder: (buildContext, index) =>
            {
                if (widget.hasMoreMembers[widget.selectedChannelId] && index == rowCount - 1)
                {
                    return(new Container(
                               height: 78,
                               alignment: Alignment.center,
                               child: new LoadTrigger(
                                   onLoad: () =>
                    {
                        var offset = widget.members.ContainsKey(channel.id)
                                            ? widget.members[channel.id].Count
                                            : 0;
                        Utils.Get <GetMembersResponse>(
                            $"/api/connectapp/channels/{channel.id}/members?offset={offset}"
                            ).Then(response =>
                        {
                            response.list.ForEach(member =>
                            {
                                if (widget.members[channel.id].All(m => m.user.id != member.user.id))
                                {
                                    widget.members[channel.id].Add(member);
                                }

                                widget.users.putIfAbsent(member.user.id, () => member.user);
                            });

                            m_AmIOwner = widget.members[channel.id].Any(member =>
                                                                        member.user.id == Window.currentUserId && member.role == "owner");
                            widget.hasMoreMembers[widget.selectedChannelId] = response.total > widget.members[channel.id].Count;
                            if (mounted)
                            {
                                using (WindowProvider.of(context).getScope())
                                {
                                    setState(() => { });
                                }
                            }
                        });
                    }
                                   )
                               ));
                }

                var children = new List <Widget> {
                };
                for (var i = 0; i < countPerRow; ++i)
                {
                    if (index * countPerRow + i < widget.members[channel.id].Count)
                    {
                        var member = widget.members[channel.id][index * countPerRow + i];
                        children.Add(
                            new Expanded(
                                child: new Container(
                                    height: 78,
                                    width: 240,
                                    alignment: Alignment.center,
                                    child: new Container(
                                        height: 50,
                                        padding: EdgeInsets.only(
                                            top: 6,
                                            bottom: 4
                                            ),
                                        child: new Row(
                                            children: new List <Widget>
                        {
                            new Container(
                                margin: EdgeInsets.only(right: 8),
                                child: new Avatar(member.user)
                                ),
                            new Expanded(
                                child: new Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: new List <Widget>
                            {
                                new Text(
                                    member.user.fullName,
                                    style: new TextStyle(
                                        fontSize: 14,
                                        fontWeight: FontWeight.w500,
                                        fontFamily: "PingFang"
                                        ),
                                    overflow: TextOverflow.ellipsis
                                    ),
                                new Text(
                                    member.user.title ?? string.Empty,
                                    style: new TextStyle(
                                        color: new Color(0xff5a5a5b),
                                        fontSize: 14,
                                        fontFamily: "PingFang"
                                        ),
                                    overflow: TextOverflow.ellipsis
                                    )
                            }
                                    )
                                )
                        }
                                            )
                                        )
                                    )
                                )
                            );
                    }
                    else
                    {
                        children.Add(
                            new Expanded(
                                child: new Container(
                                    height: 78,
                                    width: 240
                                    )
                                )
                            );
                    }
                }

                return(new Container(
                           margin: EdgeInsets.symmetric(horizontal: 24),
                           decoration: new BoxDecoration(
                               border: new Border(
                                   top: new BorderSide(
                                       color: new Color(0xfff0f0f0)
                                       )
                                   )
                               ),
                           child: new Row(
                               mainAxisAlignment: MainAxisAlignment.start,
                               children: children
                               )
                           ));
            },
                    childCount: rowCount
                    )
                );

            var headerChildren = new List <Widget>
            {
                new Expanded(
                    child: new Text(
                        $"{channel.name}",
                        style: new TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.w500,
                            color: new Color(0xff212121),
                            fontFamily: "PingFang"
                            )
                        )
                    ),
            };

            headerChildren.Add(
                new GestureDetector(
                    onTap: () =>
            {
                if (screenWidth < 750)
                {
                    m_AnimationController.reverse();
                }
                else
                {
                    HomePage.of(this.context).HideChannelInfo();
                }
            },
                    child: new Icon(
                        IconFont.IconFontClose,
                        color: new Color(0xff979a9e),
                        size: 28
                        )
                    )
                );

            Widget all = new Container(
                color: new Color(0xffffffff),
                child: new Scroller(
                    child: new CustomScrollView(
                        slivers: new List <Widget>
            {
                new SliverToBoxAdapter(
                    child: new Container(
                        height: 64,
                        decoration: new BoxDecoration(
                            border: new Border(
                                bottom: new BorderSide(
                                    color: new Color(0xffd8d8d8)
                                    )
                                )
                            ),
                        padding: EdgeInsets.symmetric(horizontal: 24),
                        alignment: Alignment.center,
                        child: new Row(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: headerChildren
                            )
                        )
                    ),
                MediaQuery.of(context).size.width < 750 ? BuildNarrowInfo() : BuildWideInfo(),
                new SliverToBoxAdapter(
                    child: new Container(
                        decoration: new BoxDecoration(
                            border: new Border(
                                top: new BorderSide(
                                    color: new Color(0xffd8d8d8)
                                    ),
                                bottom: new BorderSide(
                                    color: new Color(0xffd8d8d8)
                                    )
                                )
                            ),
                        padding: EdgeInsets.symmetric(vertical: 18),
                        margin: EdgeInsets.symmetric(horizontal: 24),
                        height: 78,
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: new List <Widget>
                {
                    new Column(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: new List <Widget>
                    {
                        new Text(
                            "消息免打扰",
                            style: new TextStyle(
                                fontSize: 14,
                                color: new Color(0xff212121),
                                fontFamily: "PingFang"
                                )
                            ),
                        new Text(
                            "打开后,将不会收到消息提醒",
                            style: new TextStyle(
                                fontSize: 14,
                                color: new Color(0xff797979),
                                fontFamily: "PingFang"
                                )
                            ),
                    }
                        ),
                    new Switch(
                        m_MuteController
                        )
                }
                            )
                        )
                    ),
                new SliverToBoxAdapter(
                    child: new Container(
                        decoration: new BoxDecoration(
                            border: new Border(
                                bottom: new BorderSide(
                                    color: new Color(0xffd8d8d8)
                                    )
                                )
                            ),
                        padding: EdgeInsets.symmetric(vertical: 18),
                        margin: EdgeInsets.symmetric(horizontal: 24),
                        height: 78,
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: new List <Widget>
                {
                    new Column(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: new List <Widget>
                    {
                        new Text(
                            "设为置顶",
                            style: new TextStyle(
                                fontSize: 14,
                                color: new Color(0xff212121),
                                fontFamily: "PingFang"
                                )
                            ),
                        new Text(
                            "打开后,当前群聊将会被置顶在群聊列表",
                            style: new TextStyle(
                                fontSize: 14,
                                color: new Color(0xff797979),
                                fontFamily: "PingFang"
                                )
                            )
                    }
                        ),
                    new Switch(
                        m_PinController
                        )
                }
                            )
                        )
                    ),
                new SliverToBoxAdapter(
                    child: new Container(
                        margin: EdgeInsets.only(top: 24, left: 24, right: 24),
                        padding: EdgeInsets.only(bottom: 8),
                        child: new Text(
                            $"群聊成员({channel.memberCount})",
                            style: new TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.w500,
                                fontFamily: "PingFang"
                                )
                            )
                        )
                    ),
                members,
                new SliverToBoxAdapter(
                    child: new Container(
                        height: 56
                        )
                    )
            }
                        )
                    )
                );

            var stacked = new List <Widget> {
                all
            };

            if (!m_AmIOwner)
            {
                var quitButtonChildren = new List <Widget>();
                if (m_Quiting)
                {
                    quitButtonChildren.Add(
                        new Text(
                            "退出群聊",
                            style: new TextStyle(
                                fontSize: 18,
                                color: new Color(0x00000000),
                                fontFamily: "PingFang"
                                )
                            )
                        );
                    quitButtonChildren.Add(
                        new Loading(
                            size: 24
                            )
                        );
                }
                else
                {
                    quitButtonChildren.Add(new Text(
                                               "退出群聊",
                                               style: new TextStyle(
                                                   fontSize: 18,
                                                   color: new Color(0xfff44336),
                                                   fontFamily: "PingFang"
                                                   )
                                               )
                                           );
                }

                stacked.Add(
                    new Positioned(
                        bottom: 0,
                        left: 0,
                        right: 0,
                        child: new GestureDetector(
                            onTap: () =>
                {
                    if (m_Quiting)
                    {
                        return;
                    }
                    setState(() => m_Quiting = true);
                    var requestUrl           = string.IsNullOrEmpty(channel.groupId)
                                    ? $"/api/connectapp/v1/channels/{channel.id}/leave"
                                    : $"/api/connectapp/v1/groups/{channel.groupId}/leave";
                    var state = HomePage.of(context);
                    Utils.Post <Models.Channel>(
                        requestUrl,
                        "{}"
                        ).Then(c =>
                    {
                        state.Select(string.Empty);
                        state.RemoveChannel(channel);
                    });
                },
                            child: new Container(
                                height: 56,
                                decoration: new BoxDecoration(
                                    color: new Color(0xffffffff),
                                    border: new Border(
                                        top: new BorderSide(
                                            color: new Color(0xffd8d8d8)
                                            )
                                        )
                                    ),
                                alignment: Alignment.center,
                                child: new Stack(
                                    children: quitButtonChildren
                                    )
                                )
                            )
                        )
                    );
            }

            all = new Stack(
                children: stacked
                );

            if (screenWidth < 750)
            {
                all = Transform.translate(
                    offset: new Offset(0, (1 - m_AnimationController.value) * screenHeight),
                    child: all
                    );
            }

            return(all);
        }
Пример #18
0
        public override Widget build(BuildContext context)
        {
            var screenWidth    = MediaQuery.of(context).size.width;
            var windowChildren = new List <Widget>
            {
                new Scroller(
                    child: ListView.builder(
                        controller: m_ScrollController,
                        reverse: true,
                        itemCount: m_HasMoreOld
                            ? widget.messages[widget.channel.id].Count + 1
                            : widget.messages[widget.channel.id].Count,
                        itemBuilder: (ctx, index) =>
                {
                    if (!m_Initialized)
                    {
                        return(new Container());
                    }

                    if (index == widget.messages[widget.channel.id].Count)
                    {
                        return(new LoadTrigger(
                                   () =>
                        {
                            var lastMessageId =
                                widget.messages[widget.channel.id].last().id;
                            Get(
                                $"/api/connectapp/v1/channels/{widget.channel.id}/messages?before={lastMessageId}",
                                (GetMessagesResponse getMessagesResponse) =>
                            {
                                if (mounted)
                                {
                                    using (WindowProvider.of(context)
                                           .getScope())
                                    {
                                        setState(() =>
                                        {
                                            widget.messages[widget.channel.id]
                                            .AddRange(
                                                getMessagesResponse.items
                                                .Where(
                                                    item =>
                                                    item.id !=
                                                    lastMessageId
                                                    )
                                                );
                                            m_MsgsUnreads = 0;
                                            m_HasMoreUnreads = true;
                                            if (m_PreviousLastMsgId == null)
                                            {
                                                m_HasMoreUnreads = false;
                                            }
                                            else
                                            {
                                                foreach (var m in widget.messages[widget.channel.id])
                                                {
                                                    if (string.Compare(m.id, m_PreviousLastMsgId) > 0)
                                                    {
                                                        ++m_MsgsUnreads;
                                                    }
                                                    else
                                                    {
                                                        m_HasMoreUnreads = false;
                                                        break;
                                                    }
                                                }
                                            }

                                            m_HasMoreOld =
                                                getMessagesResponse.hasMore;
                                        });
                                    }
                                }
                            });
                        }
                                   ));
                    }

                    var currentMessage = widget.messages[widget.channel.id][index];
                    var msgTime        =
                        ExtractTimeFromSnowflakeId(currentMessage.id.IsNullOrEmpty()
                                    ? currentMessage.nonce
                                    : currentMessage.id);
                    bool showTime;
                    var isNew = false;
                    if (index == widget.messages[widget.channel.id].Count - 1)
                    {
                        showTime = true;
                    }
                    else
                    {
                        var nextMessage = widget.messages[widget.channel.id][index + 1];
                        showTime        = msgTime - ExtractTimeFromSnowflakeId(
                            nextMessage.id.IsNullOrEmpty()
                                                   ? nextMessage.nonce
                                                   : nextMessage.id) >
                                          TimeSpan.FromMinutes(5);
                        if (nextMessage.id != null && nextMessage.id == m_PreviousLastMsgId)
                        {
                            isNew = true;
                        }
                    }

                    Action onBuild = null;
                    if (currentMessage.id == m_PreviousLastMsgId)
                    {
                        onBuild = () =>
                        {
                            SchedulerBinding.instance.addPostFrameCallback(value =>
                            {
                                setState(() =>
                                {
                                    m_MsgsUnreads    = 0;
                                    m_HasMoreUnreads = false;
                                });
                            });
                        };
                    }

                    return(new Message(
                               widget.messages[widget.channel.id][index],
                               widget.users,
                               showTime,
                               m_PreviousLastMsgId != widget.channel.lastMessage.id && isNew,
                               msgTime,
                               onBuild
                               ));
                }
                        )
                    ),
            };

            if (Window.reconnecting)
            {
                windowChildren.Add(
                    new Positioned(
                        left: 0,
                        top: 0,
                        right: 0,
                        child: new Container(
                            color: new Color(0xfffde1df),
                            height: 48,
                            alignment: Alignment.center,
                            child: new Text(
                                "网络未连接,正在连接中",
                                style: new TextStyle(
                                    fontSize: 16,
                                    color: new Color(0xfff44336),
                                    fontFamily: "PingFang"
                                    )
                                )
                            )
                        )
                    );
            }

            var newMsgsCount = Window.NewMessages.Count(msg => msg.author.id != Window.currentUserId);

            if (newMsgsCount != 0)
            {
                windowChildren.Add(
                    new Positioned(
                        bottom: 24,
                        child: new GestureDetector(
                            onTap: () =>
                {
                    Window.NewMessages.ForEach(msg => { Window.Messages[msg.channelId].Insert(0, msg); });
                    Window.NewMessages.Clear();
                    setState();
                    m_ScrollController.animateTo(
                        0,
                        new TimeSpan(0, 0, 0, 0, 480),
                        Curves.easeInOut
                        );
                },
                            child: new Container(
                                height: 40,
                                padding: EdgeInsets.symmetric(horizontal: 16),
                                decoration: new BoxDecoration(
                                    borderRadius: BorderRadius.all(20),
                                    boxShadow: new List <BoxShadow>
                {
                    new BoxShadow(
                        offset: new Offset(0, 1),
                        blurRadius: 6,
                        color: new Color(0x19000000)
                        ),
                },
                                    color: new Color(0xffffffff)
                                    ),
                                child: new Row(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: new List <Widget>
                {
                    new Text(
                        $"{newMsgsCount}条新消息未读",
                        style: new TextStyle(
                            color: new Color(0xff2196f3),
                            fontSize: 14,
                            fontFamily: "PingFang"
                            )
                        ),
                }
                                    )
                                )
                            )
                        )
                    );
            }

            if (m_MsgsUnreads > 0)
            {
                var text = $"{m_MsgsUnreads}";
                if (m_HasMoreUnreads)
                {
                    text += "+";
                }

                text += "条新消息";
                windowChildren.Add(
                    new Positioned(
                        top: 24,
                        child: new GestureDetector(
                            onTap: () =>
                {
                    var totalHeight = 0.0f;
                    for (var index = 0; index < widget.messages[widget.channel.id].Count; ++index)
                    {
                        var message = widget.messages[widget.channel.id][index];
                        if (string.Compare(message.id, m_PreviousLastMsgId) > 0)
                        {
                            var showTime = true;
                            var msgTime  =
                                ExtractTimeFromSnowflakeId(message.id.IsNullOrEmpty()
                                                ? message.nonce
                                                : message.id);
                            if (index != widget.messages[widget.channel.id].Count - 1)
                            {
                                var nextMessage = widget.messages[widget.channel.id][index + 1];
                                showTime        = msgTime - ExtractTimeFromSnowflakeId(
                                    nextMessage.id.IsNullOrEmpty()
                                                               ? nextMessage.nonce
                                                               : nextMessage.id) >
                                                  TimeSpan.FromMinutes(5);
                            }

                            var layoutWidth = screenWidth * 0.7f;
                            if (screenWidth >= 750)
                            {
                                layoutWidth -= 286.5f;
                            }
                            else
                            {
                                layoutWidth -= 24f;
                            }

                            totalHeight += CalculateMessageHeight(
                                message,
                                showTime,
                                layoutWidth
                                );
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (m_HasMoreUnreads)
                    {
                        totalHeight += 40;
                    }
                    else
                    {
                        totalHeight += 36;
                    }

                    m_ScrollController.animateTo(
                        totalHeight - MediaQuery.of(context).size.height + 184,
                        new TimeSpan(0, 0, 0, 0, 480),
                        Curves.easeInOut
                        );
                    if (!m_HasMoreUnreads)
                    {
                        setState(() =>
                        {
                            m_MsgsUnreads    = 0;
                            m_HasMoreUnreads = false;
                        });
                    }
                },
                            child: new Container(
                                height: 40,
                                padding: EdgeInsets.symmetric(horizontal: 16),
                                decoration: new BoxDecoration(
                                    borderRadius: BorderRadius.all(20),
                                    boxShadow: new List <BoxShadow>
                {
                    new BoxShadow(
                        offset: new Offset(0, 1),
                        blurRadius: 6,
                        color: new Color(0x19000000)
                        ),
                },
                                    color: new Color(0xffffffff)
                                    ),
                                child: new Row(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: new List <Widget>
                {
                    new Text(
                        text,
                        style: new TextStyle(
                            color: new Color(0xff2196f3),
                            fontSize: 14,
                            fontFamily: "PingFang"
                            )
                        ),
                    new Container(
                        margin: EdgeInsets.only(left: 4),
                        child: Transform.rotate(
                            child: new Icon(
                                IconFont.IconFontArrowUp,
                                size: 24,
                                color: new Color(0xff2196f3)
                                )
                            )
                        )
                }
                                    )
                                )
                            )
                        )
                    );
            }

            var rootState = HomePage.of(context);

            var children = new List <Widget>
            {
                new Container(
                    color: new Color(0xffffffff),
                    child: new Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: new List <Widget>
                {
                    new ChattingWindowHeader(
                        widget.channel, () =>
                    {
                        if (screenWidth < 750)
                        {
                            m_AnimationController.reverse();
                        }
                        else
                        {
                            HomePage.of(context).Select(string.Empty);
                        }
                    }),
                    new Expanded(
                        child: new Stack(
                            alignment: Alignment.center,
                            children: windowChildren
                            )
                        ),
                    new Sender(
                        m_SenderFocusNode,
                        widget.users),
                }
                        )
                    ),
            };

            if (!m_Initialized)
            {
                children.Add(
                    new Container(
                        alignment: Alignment.center,
                        child: new Loading(size: 56)
                        )
                    );
            }

            Widget all = new GestureDetector(
                onTap: () => { FocusScope.of(context).requestFocus(m_EmptyFocusNode); },
                child: new Stack(
                    children: children
                    )
                );

            if (screenWidth < 750)
            {
                all = Transform.translate(
                    offset: new Offset((1 - m_AnimationController.value) * screenWidth, 0),
                    child: all
                    );
            }

            return(all);
        }
Пример #19
0
        public override Widget build(BuildContext context)
        {
            var screenWidth    = MediaQuery.of(context).size.width;
            var headerChildren = new List <Widget>
            {
                new Text(
                    "发现群聊",
                    style: HeaderTextStyle
                    )
            };

            if (screenWidth < 750)
            {
                headerChildren.Insert(
                    0,
                    new GestureDetector(
                        onTap: () => m_AnimationController.reverse(),
                        child: new Container(
                            width: 28,
                            height: 28,
                            margin: EdgeInsets.only(right: 12),
                            child: new Icon(
                                IconFont.IconFontArrowBack,
                                size: 28,
                                color: new Color(0xff979a9e)
                                )
                            )
                        )
                    );
            }

            var children = new List <Widget>
            {
                new Container(
                    height: 64,
                    padding: HeaderTextPadding,
                    alignment: Alignment.centerLeft,
                    decoration: new BoxDecoration(
                        border: new Border(
                            bottom: new BorderSide(
                                color: new Color(0xffd8d8d8),
                                width: 1
                                )
                            )
                        ),
                    child: new Row(
                        children: headerChildren
                        )
                    ),
            };

            if (widget.channels == null || widget.channels.Count == 0)
            {
                children.Add(
                    new Expanded(
                        child: new Container(
                            alignment: Alignment.center,
                            child: new Loading(
                                size: 56
                                )
                            )
                        )
                    );
            }
            else
            {
                var canvasWidth = screenWidth - 64;
                if (screenWidth >= 750)
                {
                    canvasWidth -= 375;
                }

                var countPerRow = (canvasWidth / 316).floor();
                var itemWidth   = canvasWidth / (float)countPerRow - 16;
                var rowCount    = (widget.channels.Count / (float)countPerRow).ceil();
                var rows        = new List <Widget> {
                };
                for (var i = 0; i < rowCount; ++i)
                {
                    var items = new List <Widget> {
                    };
                    for (var j = 0; j < countPerRow && i * countPerRow + j < widget.channels.Count; ++j)
                    {
                        items.Add(
                            new SquareLobbyCard(
                                widget.channels.Values.ToArray()[i * countPerRow + j],
                                widget.channels,
                                widget.groups,
                                itemWidth
                                )
                            );
                    }

                    rows.Add(
                        new Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: items
                            )
                        );
                }

                children.Add(
                    new Expanded(
                        child: new Scroller(
                            child: new SingleChildScrollView(
                                child: new Container(
                                    padding: EdgeInsets.all(32),
                                    child: new Column(
                                        children: rows
                                        )
                                    )
                                )
                            )
                        )
                    );
            }

            Widget all = new Container(
                color: HeaderBackgroundColor,
                child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: children
                    )
                );

            if (screenWidth < 750)
            {
                all = Transform.translate(
                    offset: new Offset((1 - m_AnimationController.value) * screenWidth, 0),
                    child: all
                    );
            }

            return(all);
        }