Beispiel #1
0
 public override void debugFillProperties(DiagnosticPropertiesBuilder properties)
 {
     base.debugFillProperties(properties);
     properties.add(
         new DiagnosticsProperty <TextEditingController>("controller", this.controller, defaultValue: null));
     properties.add(new DiagnosticsProperty <FocusNode>("focusNode", this.focusNode, defaultValue: null));
     properties.add(new DiagnosticsProperty <bool?>("enabled", this.enabled, defaultValue: null));
     properties.add(new DiagnosticsProperty <InputDecoration>("decoration", this.decoration, defaultValue: new InputDecoration()));
     properties.add(new DiagnosticsProperty <TextInputType>("keyboardType", this.keyboardType,
                                                            defaultValue: TextInputType.text));
     properties.add(new DiagnosticsProperty <TextStyle>("style", this.style, defaultValue: null));
     properties.add(new DiagnosticsProperty <bool>("autofocus", this.autofocus, defaultValue: false));
     properties.add(new DiagnosticsProperty <bool>("obscureText", this.obscureText, defaultValue: false));
     properties.add(new DiagnosticsProperty <bool>("autocorrect", this.autocorrect, defaultValue: true));
     properties.add(new IntProperty("maxLines", this.maxLines, defaultValue: 1));
     properties.add(new IntProperty("maxLength", this.maxLength, defaultValue: null));
     properties.add(new FlagProperty("maxLengthEnforced", value: this.maxLengthEnforced, defaultValue: true,
                                     ifFalse: "maxLength not enforced"));
     properties.add(new EnumProperty <TextInputAction?>("textInputAction", this.textInputAction, defaultValue: null));
     properties.add(new EnumProperty <TextCapitalization>("textCapitalization", this.textCapitalization, defaultValue: TextCapitalization.none));
     properties.add(new EnumProperty <TextAlign>("textAlign", this.textAlign, defaultValue: TextAlign.left));
     properties.add(new EnumProperty <TextDirection>("textDirection", this.textDirection, defaultValue: null));
     properties.add(new FloatProperty("cursorWidth", this.cursorWidth, defaultValue: 2.0));
     properties.add(new DiagnosticsProperty <Radius>("cursorRadius", this.cursorRadius, defaultValue: null));
     properties.add(new DiagnosticsProperty <Color>("cursorColor", this.cursorColor, defaultValue: null));
     properties.add(new DiagnosticsProperty <Brightness?>("keyboardAppearance", this.keyboardAppearance, defaultValue: null));
     properties.add(new DiagnosticsProperty <EdgeInsets>("scrollPadding", this.scrollPadding, defaultValue: EdgeInsets.all(20.0f)));
     properties.add(new FlagProperty("selectionEnabled", value: this.selectionEnabled, defaultValue: true, ifFalse: "selection disabled"));
 }
Beispiel #2
0
        public override Widget buildToolbar(
            BuildContext context,
            Rect globalEditableRegion,
            float textLineHeight,
            Offset position,
            List <TextSelectionPoint> endpoints,
            TextSelectionDelegate _delegate
            )
        {
            D.assert(WidgetsD.debugCheckHasMediaQuery(context));
            MediaQueryData mediaQuery = MediaQuery.of(context);

            float toolbarHeightNeeded = mediaQuery.padding.top
                                        + CupertinoTextSelectionUtils._kToolbarScreenPadding
                                        + CupertinoTextSelectionUtils._kToolbarHeight
                                        + CupertinoTextSelectionUtils._kToolbarContentDistance;
            float availableHeight     = globalEditableRegion.top + endpoints.first().point.dy - textLineHeight;
            bool  isArrowPointingDown = toolbarHeightNeeded <= availableHeight;

            float arrowTipX = (position.dx + globalEditableRegion.left).clamp(
                CupertinoTextSelectionUtils._kArrowScreenPadding + mediaQuery.padding.left,
                mediaQuery.size.width - mediaQuery.padding.right - CupertinoTextSelectionUtils._kArrowScreenPadding
                );
            float localBarTopY = isArrowPointingDown
                  ? endpoints.first().point.dy - textLineHeight - CupertinoTextSelectionUtils._kToolbarContentDistance - CupertinoTextSelectionUtils._kToolbarHeight
                  : endpoints.last().point.dy + CupertinoTextSelectionUtils._kToolbarContentDistance;

            List <Widget> items = new List <Widget> {
            };
            Widget onePhysicalPixelVerticalDivider = new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio);
            CupertinoLocalizations localizations   = CupertinoLocalizations.of(context);
            EdgeInsets             arrowPadding    = isArrowPointingDown
                  ? EdgeInsets.only(bottom: CupertinoTextSelectionUtils._kToolbarArrowSize.height)
                  : EdgeInsets.only(top: CupertinoTextSelectionUtils._kToolbarArrowSize.height);

            void addToolbarButtonIfNeeded(
                string text,
                Predicate predicate,
                OnPressed onPressed)
            {
                if (!predicate(_delegate))
                {
                    return;
                }

                if (items.isNotEmpty())
                {
                    items.Add(onePhysicalPixelVerticalDivider);
                }

                items.Add(new CupertinoButton(
                              child: new Text(text, style: CupertinoTextSelectionUtils._kToolbarButtonFontStyle),
                              color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
                              minSize: CupertinoTextSelectionUtils._kToolbarHeight,
                              padding: CupertinoTextSelectionUtils._kToolbarButtonPadding.add(arrowPadding),
                              borderRadius: null,
                              pressedOpacity: 0.7f,
                              onPressed: () => onPressed(_delegate)
                              ));
            }

            addToolbarButtonIfNeeded(localizations.cutButtonLabel, canCut, handleCut);
            addToolbarButtonIfNeeded(localizations.copyButtonLabel, canCopy, handleCopy);
            addToolbarButtonIfNeeded(localizations.pasteButtonLabel, canPaste, handlePaste);
            addToolbarButtonIfNeeded(localizations.selectAllButtonLabel, canSelectAll, handleSelectAll);
            return(new CupertinoTextSelectionToolbar(
                       barTopY: localBarTopY + globalEditableRegion.top,
                       arrowTipX: arrowTipX,
                       isArrowPointingDown: isArrowPointingDown,
                       child: items.isEmpty() ? null : new DecoratedBox(
                           decoration: new BoxDecoration(color: CupertinoTextSelectionUtils._kToolbarDividerColor),
                           child: new Row(mainAxisSize: MainAxisSize.min, children: items)
                           )
                       ));
        }
Beispiel #3
0
 public CustomSegmentedControl(
     List <object> items,
     List <Widget> children,
     ValueChanged <int> onValueChanged = null,
     int currentIndex               = 0,
     float headerHeight             = 44,
     Widget trailing                = null,
     Decoration headerDecoration    = null,
     Decoration indicator           = null,
     EdgeInsets headerPadding       = null,
     EdgeInsets labelPadding        = null,
     float?indicatorWidth           = null,
     Color unselectedColor          = null,
     Color selectedColor            = null,
     TextStyle unselectedTextStyle  = null,
     TextStyle selectedTextStyle    = null,
     CustomTabController controller = null,
     ScrollPhysics physics          = null,
     ValueChanged <int> onTap       = null,
     Key key = null
     ) : base(key: key)
 {
     D.assert(items != null);
     D.assert(items.Count >= 2);
     D.assert(children != null);
     D.assert(children.Count >= 2);
     D.assert(children.Count == items.Count);
     D.assert(currentIndex < children.Count);
     this.items            = items;
     this.children         = children;
     this.onValueChanged   = onValueChanged;
     this.unselectedColor  = unselectedColor ?? CColors.TextBody4;
     this.selectedColor    = selectedColor ?? CColors.TextTitle;
     this.currentIndex     = currentIndex;
     this.headerHeight     = headerHeight;
     this.trailing         = trailing;
     this.headerDecoration = headerDecoration ?? new BoxDecoration(
         color: CColors.White,
         border: new Border(bottom: new BorderSide(color: CColors.Separator2))
         );
     this.indicator = indicator ?? new CustomGradientsTabIndicator(
         insets: EdgeInsets.zero,
         height: 8,
         gradient: new LinearGradient(
             begin: Alignment.centerLeft,
             end: Alignment.centerRight,
             new List <Color> {
         new Color(0xFFB1E0FF),
         new Color(0xFF6EC6FF)
     }
             )
         );
     this.headerPadding       = headerPadding ?? EdgeInsets.only(bottom: 10);
     this.labelPadding        = labelPadding ?? EdgeInsets.symmetric(horizontal: 16);
     this.indicatorWidth      = indicatorWidth;
     this.unselectedTextStyle = unselectedTextStyle ?? new TextStyle(
         fontSize: 16,
         fontFamily: "Roboto-Regular",
         color: this.unselectedColor
         );
     this.selectedTextStyle = selectedTextStyle ?? new TextStyle(
         fontSize: 16,
         fontFamily: "Roboto-Medium",
         color: this.unselectedColor
         );
     this.controller = controller;
     this.physics    = physics;
     this.onTap      = onTap;
 }
Beispiel #4
0
        public static Widget SettingHSVColorPicker(
            BuildContext context,
            string title,
            ValueChanged <Color> onColorChanged,
            Color color            = null,
            string buttonName      = "",
            bool enableAlpha       = false,
            bool showPreviousColor = false
            )
        {
            if (color == null)
            {
                color = Colors.blueAccent;
            }
            if (buttonName == "")
            {
                buttonName = color.ToHexString(enableAlpha);
            }

            return(new Container(
                       padding: EdgeInsets.symmetric(horizontal: 6f),
                       child: new Row(
                           children: new List <Widget>
            {
                new Container(child: new Text(title)),
                new Expanded(
                    child: new Container(
                        padding: EdgeInsets.all(6),
                        alignment: Alignment.bottomRight,
                        child:  new RaisedButton(
                            color: color,
                            child: new Text(
                                buttonName,
                                style: new TextStyle(
                                    color: Utils.useWhiteForeground(color) ? Colors.white : Colors.black
                                    ) //TextStyle
                                ),    //Text
                            onPressed: () => {
                    DialogUtils.showDialog(
                        context: context,
                        builder: (BuildContext _) => {
                        if (showPreviousColor)
                        {
                            return new AlertDialog(
                                titlePadding: EdgeInsets.all(0),
                                contentPadding: EdgeInsets.all(0f),
                                shape: new RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(25)
                                    ),                    //RoundedRectangleBorder
                                content: new SingleChildScrollView(
                                    child: new SlidePicker(
                                        pickerColor: color,
                                        onColorChanged: onColorChanged,
                                        paletteType: PaletteType.hsv,
                                        enableAlpha: enableAlpha,
                                        displayThumbColor: true,
                                        showLabel: false,
                                        showIndicator: true,
                                        indicatorBorderRadius: BorderRadius.vertical(top: Radius.circular(25))
                                        )             //SlidePicker
                                    )                 //SingleChildScrollView
                                );                    //AlertDialog
                        }
                        else
                        {
                            return new AlertDialog(
                                titlePadding: EdgeInsets.all(0f),
                                contentPadding: EdgeInsets.all(0f),
                                content: new SingleChildScrollView(
                                    child: new ColorPicker(
                                        pickerColor: color,
                                        onColorChanged: onColorChanged,
                                        colorPickerWidth: 300f,
                                        pickerAreaHeightPercent: 0.7f,
                                        enableAlpha: enableAlpha,
                                        displayThumbColor: true,
                                        showLabel: true,
                                        paletteType: PaletteType.hsv,
                                        pickerAreaBorderRadius: BorderRadius.only(
                                            topLeft: Radius.circular(2f),
                                            topRight: Radius.circular(2f)
                                            )         //BorderRadius
                                        )             //ColorPicker
                                    )                 //SingleChildScrollView
                                );                    //AlertDialog
                        }
                    }
                        );
                }
                            )
                        )    //container
                    ),       //expanded
            }                //list
                           ) //row
                       ));
        }
Beispiel #5
0
        public override Widget build(BuildContext context)
        {
            var mediaQueryData = MediaQuery.of(context);

            return(new Column(
                       mainAxisAlignment: MainAxisAlignment.end,
                       children: new List <Widget> {
                new Container(
                    color: CColors.White,
                    width: mediaQueryData.size.width,
                    height: this.projectType == ProjectType.article ? 319 : 211 + mediaQueryData.padding.bottom,
                    child: new Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: new List <Widget> {
                    new Container(
                        height: 54,
                        padding: EdgeInsets.only(top: 16, left: 16),
                        child: new Text("分享至", style: CTextStyle.PRegularBody4)
                        ),
                    new Container(
                        height: 108,
                        padding: EdgeInsets.only(top: 16),
                        decoration: new BoxDecoration(
                            border: new Border(
                                new BorderSide(CColors.Separator2),
                                bottom: new BorderSide(CColors.Separator2)
                                )
                            ),
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: this._buildShareItems()
                            )
                        ),
                    this.projectType == ProjectType.article
                                    ? new Container(
                        height: 108,
                        padding: EdgeInsets.only(top: 16),
                        decoration: new BoxDecoration(
                            border: new Border(
                                bottom: new BorderSide(CColors.Separator2)
                                )
                            ),
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: this._buildOtherItems()
                            )
                        )
                                    : new Container(),
                    new GestureDetector(
                        onTap: () => {
                        if (Router.navigator.canPop())
                        {
                            Router.navigator.pop();
                        }
                    },
                        child: new Container(
                            height: 49,
                            color: CColors.Transparent,
                            alignment: Alignment.center,
                            child: new Text("取消", style: CTextStyle.PLargeBody)
                            )
                        ),
                    new Container(
                        height: mediaQueryData.padding.bottom
                        )
                }
                        )
                    )
            }
                       ));
        }
Beispiel #6
0
        public List <Widget> BuildNavigations()
        {
            var navigations = new List <Widget>
            {
                new SliverToBoxAdapter(
                    child: CreateChannelsListHeader()
                    ),
            };

            if (Window.socketConnected)
            {
                if (widget.channels.Count > 0)
                {
                    var sortedChannels = widget.channels.Values.ToList();
                    sortedChannels.Sort((c1, c2) =>
                    {
                        if (!c1.stickTime.IsNullOrEmpty() && c2.stickTime.IsNullOrEmpty())
                        {
                            return(-1);
                        }

                        if (c1.stickTime.IsNullOrEmpty() && !c2.stickTime.IsNullOrEmpty())
                        {
                            return(1);
                        }

                        var d2 = ExtractTimeFromSnowflakeId(c2.lastMessage?.id ?? c2.id);
                        var d1 = ExtractTimeFromSnowflakeId(c1.lastMessage?.id ?? c1.id);
                        return(d2.CompareTo(d1));
                    });
                    navigations.Add(
                        new SliverList(
                            del: new SliverChildBuilderDelegate(
                                builder: (buildContext, index) => new LobbyChannelCard(
                                    sortedChannels[index],
                                    widget.users,
                                    widget.readStates,
                                    SelectedChannelId == sortedChannels[index].id
                                    ),
                                childCount: widget.channels.Count
                                )
                            )
                        );
                }
                else
                {
                    navigations.Add(
                        new SliverToBoxAdapter(
                            child: new Container(
                                margin: EdgeInsets.only(left: 16, right: 16, top: 32),
                                child: new Text(
                                    "你还没有加入任何群聊,快加入感兴趣的群聊频道和大家一起讨论吧!",
                                    style: new TextStyle(
                                        fontSize: 14,
                                        color: new Color(0xff797979),
                                        fontFamily: "PingFang"
                                        )
                                    )
                                )
                            )
                        );
                }

                if (widget.discoverChannels.Count > 0)
                {
                    navigations.Add(
                        new SliverToBoxAdapter(
                            child: new Container(
                                height: 82,
                                decoration: new BoxDecoration(
                                    border: new Border(
                                        bottom: new BorderSide(
                                            color: new Color(0xffd8d8d8),
                                            width: 1
                                            )
                                        )
                                    ),
                                padding: EdgeInsets.only(left: 16, right: 16, bottom: 8),
                                alignment: Alignment.bottomCenter,
                                child: new Container(
                                    height: 24,
                                    alignment: Alignment.center,
                                    child: new Row(
                                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                        children: new List <Widget>
                    {
                        new Text(
                            "发现群聊",
                            style: new TextStyle(
                                fontSize: 16,
                                color: new Color(0xff000000),
                                fontWeight: FontWeight.w500,
                                fontFamily: "PingFang"
                                )
                            ),
                        new GestureDetector(
                            onTap: () => Select(string.Empty, true),
                            child: new Container(
                                color: new Color(0x00000000),
                                child: new Text(
                                    "查看全部",
                                    style: new TextStyle(
                                        fontSize: 16,
                                        color: new Color(0xff2196f3),
                                        fontFamily: "PingFang"
                                        )
                                    )
                                )
                            )
                    }
                                        )
                                    )
                                )
                            )
                        );
                    navigations.Add(
                        new SliverList(
                            del: new SliverChildBuilderDelegate(
                                builder: (buildContext, index) => new DiscoverChannelCard(
                                    widget.discoverChannels[index],
                                    widget.channels
                                    ),
                                childCount: widget.discoverChannels.Count
                                )
                            )
                        );
                }
            }
            else
            {
                navigations.Add(
                    new SliverToBoxAdapter(
                        child: new Container(
                            height: MediaQuery.of(context).size.height - 64,
                            alignment: Alignment.center,
                            child: new Loading(size: 64)
                            )
                        )
                    );
            }

            return(navigations);
        }
Beispiel #7
0
        public override Widget build(BuildContext context)
        {
            var stacked = new List <Widget>
            {
                new Row(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: new List <Widget>
                {
                    new Expanded(
                        child: new Container(
                            alignment: Alignment.centerLeft,
                            padding: EdgeInsets.only(left: 24, bottom: 2),
                            child: new EditableText(
                                globalKeyEventHandler: GlobalKeyEventHandler,
                                controller: m_TextEditingController,
                                focusNode: widget.focusNode,
                                style: new TextStyle(
                                    color: new Color(0xff000000),
                                    fontSize: 16,
                                    height: 28 / 22.4f,
                                    fontFamily: "PingFang"
                                    ),
                                selectionColor: new Color(0xff2199f4),
                                cursorColor: new Color(0xa0000000),
                                minLines: 1,
                                maxLines: 8,
                                onSubmitted: OnSubmitted,
                                backgroundCursorColor: new Color(0xffffffff)
                                )
                            )
                        ),
                    new GestureDetector(
                        onTap: () =>
                    {
                        var filePath = EditorUtility.OpenFilePanelWithFilters(
                            "",
                            "",
                            EmptyFilters);
                        if (filePath != null && filePath.isNotEmpty())
                        {
                            var rootState = HomePage.of(context);
                            var bytes     = File.ReadAllBytes(filePath);
                            var fileName  = System.IO.Path.GetFileName(filePath);
                            var ext       = System.IO.Path.GetExtension(fileName);
                            var nonce     = CreateNonce();
                            var mimeType  = GetMimeType(ext);
                            var form      = new List <IMultipartFormSection>
                            {
                                new MultipartFormDataSection("channel", rootState.SelectedChannelId),
                                new MultipartFormDataSection("nonce", nonce),
                                new MultipartFormDataSection("size", $"{bytes.Length}"),
                                new MultipartFormFileSection("file", bytes, fileName, mimeType)
                            };

                            PostForm <Models.Message>(
                                $"/api/channels/{rootState.SelectedChannelId}/messages/attachments",
                                form,
                                message => { },
                                out var progress
                                );
                            Window.NewMessages.ForEach(msg => Window.Messages[msg.channelId].Insert(0, msg));
                            Window.NewMessages.Clear();
                            setState();
                            SchedulerBinding.instance.addPostFrameCallback(value =>
                            {
                                ChattingWindow.currentState?.m_ScrollController.animateTo(
                                    0,
                                    new TimeSpan(0, 0, 0, 0, 480),
                                    Curves.easeInOut
                                    );
                            });

                            var attachment = new Attachment
                            {
                                local       = true,
                                url         = filePath,
                                contentType = mimeType,
                                progress    = progress,
                                filename    = fileName,
                                size        = bytes.Length,
                            };
                            if (mimeType.StartsWith("image/"))
                            {
                                var texture = new Texture2D(1, 1);
                                texture.LoadImage(bytes);
                                attachment.width  = texture.width;
                                attachment.height = texture.height;
                            }
                            rootState.InsertMessage(
                                rootState.SelectedChannelId,
                                new Models.Message
                            {
                                channelId   = rootState.SelectedChannelId,
                                content     = string.Empty,
                                nonce       = nonce,
                                embeds      = new List <Embed>(),
                                attachments = new List <Attachment>
                                {
                                    attachment,
                                },
                                author = widget.users[Window.currentUserId],
                            }
                                );
                        }
                    },
                        child: new Container(
                            margin: EdgeInsets.only(
                                right: 24,
                                left: 16
                                ),
                            child: new Icon(
                                IconFont.IconFontSendPic,
                                size: 28,
                                color: new Color(0xff979a9e)
                                )
                            )
                        ),
                }
        Widget _buildFollowButton(Following following)
        {
            var user = new User();

            if (following.type == "user")
            {
                user = this.widget.viewModel.userDict[key : following.followeeId];
            }

            var team = new Team();

            if (following.type == "team")
            {
                team = this.widget.viewModel.teamDict[key : following.followeeId];
            }

            return(new GestureDetector(
                       onTap: () => {
                if (following.type == "user")
                {
                    this.widget.actionModel.pushToUserDetail(obj: user.id);
                }

                if (following.type == "team")
                {
                    this.widget.actionModel.pushToTeamDetail(obj: team.id);
                }
            },
                       child: new Container(
                           width: this.cardWidth,
                           child: new Column(
                               children: new List <Widget> {
                new Container(
                    padding: EdgeInsets.symmetric(horizontal: 4),
                    child: following.type == "user"
                                    ? Avatar.User(
                        user: user,
                        size: this.avatarSize
                        )
                                    : Avatar.Team(
                        team: team,
                        size: this.avatarSize,
                        avatarShape: AvatarShape.circle
                        )
                    ),
                new Container(
                    child: new Text(
                        following.type == "user"
                                        ? user.fullName ?? user.name
                                        : team.name,
                        style: CTextStyle.PRegularBody,
                        textAlign: TextAlign.center,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis
                        )
                    )
            }
                               )
                           )
                       ));
        }
        Widget _buildArticleList(BuildContext context)
        {
            Widget content;
            var    recommendArticleIds = this.widget.viewModel.recommendArticleIds;

            if (!this._hasBeenLoadedData || this.widget.viewModel.articlesLoading && recommendArticleIds.isEmpty())
            {
                content = ListView.builder(
                    physics: new NeverScrollableScrollPhysics(),
                    itemCount: 6,
                    itemBuilder: (cxt, index) => new ArticleLoading()
                    );
            }
            else if (recommendArticleIds.isEmpty())
            {
                content = new Container(
                    padding: EdgeInsets.only(bottom: CConstant.TabBarHeight +
                                             CCommonUtils.getSafeAreaBottomPadding(context: context)),
                    child: new BlankView(
                        "哎呀,暂无推荐文章",
                        "image/default-article",
                        true,
                        () => {
                    this.widget.actionModel.startFetchArticles();
                    this.widget.actionModel.fetchArticles(arg1: this.widget.viewModel.currentUserId,
                                                          arg2: initOffset);
                }
                        )
                    );
            }
            else
            {
                var items        = this._buildItems(recommendArticleIds);
                var enablePullUp = this.widget.viewModel.hottestHasMore;
                content = new CustomListView(
                    controller: this._refreshController,
                    enablePullDown: true,
                    enablePullUp: enablePullUp,
                    onRefresh: this._onRefresh,
                    hasBottomMargin: true,
                    itemCount: items.Count,
                    itemBuilder: (cxt, index) => items[index],
                    headerWidget: new Column(
                        children: new List <Widget> {
                    this._buildSwiper(),
                    new KingKongView(
                        leaderBoardUpdatedTime: this.widget.viewModel.leaderBoardUpdatedTime,
                        type => {
                        if (type == KingKongType.dailyCollection)
                        {
                            var articleId = this.widget.viewModel.dailySelectionId;
                            this.widget.actionModel.pushToArticleDetail(obj: articleId);
                        }

                        if (type == KingKongType.leaderBoard)
                        {
                            this.widget.actionModel.pushToLeaderBoard();
                        }

                        if (type == KingKongType.activity)
                        {
                            this.widget.actionModel.pushToHomeEvent();
                        }

                        if (type == KingKongType.blogger)
                        {
                            this.widget.actionModel.pushToBlogger();
                        }
                    }
                        )
                }
                        ),
                    footerWidget: enablePullUp?null: new EndView(hasBottomMargin: true),
                    hasScrollBar: false
                    );
            }

            return(new CustomScrollbar(child: content));
        }
        public override Widget build(BuildContext context)
        {
            D.assert(WidgetsD.debugCheckHasDirectionality(context));
            D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
            D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));

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

            if (this.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.body2,
                            overflow: TextOverflow.ellipsis,
                            child: this.widget.accountName
                            )
                        )
                    );
                children.Add(accountNameLine);
            }

            if (this.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.body1,
                            overflow: TextOverflow.ellipsis,
                            child: this.widget.accountEmail
                            )
                        )
                    );
                children.Add(accountEmailLine);
            }

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

            Widget accountDetails = new CustomMultiChildLayout(
                layoutDelegate: new _AccountDetailsLayout(),
                children: children
                );

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

            return(new SizedBox(
                       height: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
                       child: accountDetails
                       ));
        }
        Widget _buildFollowingList()
        {
            var followings = this.widget.viewModel.followings;

            if (followings.isEmpty())
            {
                return(new Container());
            }

            var followButtons = new List <Widget>();

            if (followings.Count > 5)
            {
                followings = followings.GetRange(0, 5);
            }

            for (int i = 0; i < followings.Count; i++)
            {
                var following    = followings[index : i];
                var followButton = this._buildFollowButton(following: following);
                followButtons.Add(item: followButton);
                if (i < followings.Count - 1)
                {
                    followButtons.Add(new Container(width: 10));
                }
            }

            return(new Container(
                       padding: EdgeInsets.only(bottom: 16),
                       decoration: new BoxDecoration(
                           color: CColors.White,
                           border: new Border(
                               bottom: new BorderSide(
                                   color: CColors.Background,
                                   8
                                   )
                               )
                           ),
                       child: new Column(
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: new List <Widget> {
                new Container(
                    padding: EdgeInsets.only(16, 0, 0, 12),
                    child: new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: new List <Widget> {
                    new Padding(
                        padding: EdgeInsets.only(top: 16),
                        child: new Text(
                            "最近关注",
                            style: CTextStyle.PMediumBody2
                            )
                        ),
                    new GestureDetector(
                        onTap: () =>
                        this.widget.actionModel.pushToUserFollowing(
                            obj: this.widget.viewModel.currentUserId),
                        child: new Container(
                            color: CColors.Transparent,
                            child: new Row(
                                children: new List <Widget> {
                        new Padding(
                            padding: EdgeInsets.only(16, 18),
                            child: new Text(
                                "查看全部",
                                style: new TextStyle(
                                    fontSize: 12,
                                    fontFamily: "Roboto-Regular",
                                    color: CColors.TextBody4
                                    )
                                )
                            ),
                        new Padding(
                            padding: EdgeInsets.only(top: 16, right: 8),
                            child: new Icon(
                                icon: Icons.chevron_right,
                                size: 20,
                                color: Color.fromRGBO(199, 203, 207, 1)
                                )
                            )
                    }
                                )
                            )
                        )
                }
                        )
                    ),
                new Container(
                    padding: EdgeInsets.symmetric(horizontal: 18),
                    child: new Row(
                        children: followButtons
                        )
                    )
            }
                           )
                       ));
        }
Beispiel #12
0
        public override Widget build(BuildContext context)
        {
            D.assert(MaterialD.debugCheckHasMaterial(context));
            ThemeData     theme     = Theme.of(context);
            ListTileTheme tileTheme = ListTileTheme.of(context);

            IconThemeData iconThemeData = null;

            if (this.leading != null || this.trailing != null)
            {
                iconThemeData = new IconThemeData(color: this._iconColor(theme, tileTheme));
            }

            Widget leadingIcon = null;

            if (this.leading != null)
            {
                leadingIcon = IconTheme.merge(
                    data: iconThemeData,
                    child: this.leading);
            }

            TextStyle titleStyle = this._titleTextStyle(theme, tileTheme);
            Widget    titleText  = new AnimatedDefaultTextStyle(
                style: titleStyle,
                duration: Constants.kThemeChangeDuration,
                child: this.title ?? new SizedBox()
                );

            Widget    subtitleText  = null;
            TextStyle subtitleStyle = null;

            if (this.subtitle != null)
            {
                subtitleStyle = this._subtitleTextStyle(theme, tileTheme);
                subtitleText  = new AnimatedDefaultTextStyle(
                    style: subtitleStyle,
                    duration: Constants.kThemeChangeDuration,
                    child: this.subtitle);
            }

            Widget trailingIcon = null;

            if (this.trailing != null)
            {
                trailingIcon = IconTheme.merge(
                    data: iconThemeData,
                    child: this.trailing);
            }

            EdgeInsets _defaultContentPadding = EdgeInsets.symmetric(horizontal: 16.0f);
            EdgeInsets resolvedContentPadding =
                this.contentPadding ?? tileTheme?.contentPadding ?? _defaultContentPadding;

            return(new InkWell(
                       onTap: this.enabled ? this.onTap : null,
                       onLongPress: this.enabled ? this.onLongPress : null,
                       child: new SafeArea(
                           top: false,
                           bottom: false,
                           mininum: resolvedContentPadding,
                           child: new _ListTile(
                               leading: leadingIcon,
                               title: titleText,
                               subtitle: subtitleText,
                               trailing: trailingIcon,
                               isDense: this._isDenseLayout(tileTheme),
                               isThreeLine: this.isThreeLine,
                               titleBaselineType: titleStyle.textBaseline,
                               subtitleBaselineType: subtitleStyle?.textBaseline
                               )
                           )
                       ));
        }
                public override Widget build(BuildContext buildContext)
                {
                    var container = new Container(
                        padding: EdgeInsets.only(right: 64f, top: 32, bottom: 32f),
                        child: new Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: new List <Widget>
                    {
                        new Text(
                            "欢迎使用 Unity Scripting Reference(脚本手册)!",
                            style: new TextStyle(
                                fontSize: 36,
                                height: 1.16666666667f.LineHeight(),
                                color: new Color(0xff212121)
                                )
                            ),
                        new Container(
                            margin: EdgeInsets.only(top: 36),
                            child: new RichText(
                                text: new TextSpan(
                                    children: new List <TextSpan>
                        {
                            new TextSpan(
                                "文档的这部分包含 Unity 提供的脚本 API 的详细信息。要使用这些信息,您应该了解 Unity 中脚本编写的基本理论和实践。我们使用手册的"),
                            new TextSpan(
                                " Scripting(脚本)部分",
                                style: EntranceLinkTextStyle,
                                recognizer: _scriptingSectionRecognizer
                                ),
                            new TextSpan("对此进行了解释。")
                        },
                                    style: EntranceNormalTextStyle
                                    )
                                )
                            ),
                        new Container(
                            margin: EdgeInsets.only(top: 24),
                            child: new Text(
                                "脚本引用文档是根据脚本可用的类建立的,同时会描述这些类的方法、属性以及任何与它们的用法相关的信息。",
                                style: EntranceNormalTextStyle
                                )
                            ),
                        new Container(
                            margin: EdgeInsets.only(top: 24),
                            child: new RichText(
                                text: new TextSpan(
                                    children: new List <TextSpan>
                        {
                            new TextSpan(
                                "这些页面配有大量的示例代码,您可以将这些示例代码用于任何目的,而无需说明源自 Unity。此外,您可以使用每个页面顶部的菜单以 "),
                            new TextSpan(
                                "C#",
                                style: EntranceBoldTextStyle
                                ),
                            new TextSpan(" 或 "),
                            new TextSpan(
                                "JavaScript",
                                style: EntranceBoldTextStyle
                                ),
                            new TextSpan(" 查看示例代码。请注意,无论使用哪种编程语言,API 都是相同的,所以编程语言的选择完全取决于您的喜好。")
                        },
                                    style: EntranceNormalTextStyle
                                    )
                                )
                            ),

                        new Container(
                            margin: EdgeInsets.symmetric(vertical: 24),
                            child: new RichText(
                                text: new TextSpan(
                                    children: new List <TextSpan>
                        {
                            new TextSpan("API 按其所属的 namespace 进行分组,可以从左侧的侧栏中选择。对于大多数用户,"),
                            new TextSpan("UnityEngine"),
                            new TextSpan("部分将是主要的调用端口。")
                        },
                                    style: EntranceNormalTextStyle
                                    )
                                )
                            ),
                    }
                            )
                        );

                    return(new Scroller(
                               child: new SingleChildScrollView(
                                   child: new ScrollableOverlay(
                                       child: new Container(
                                           padding: EdgeInsets.only(right: 48f),
                                           child: new Column(
                                               crossAxisAlignment: CrossAxisAlignment.stretch,
                                               children: new List <Widget>
                    {
                        new Container(
                            constraints: new BoxConstraints(
                                minHeight: MediaQuery.of(context).size.height - Header.Height -
                                SearchBar.Height - Footer.Height),
                            child: container
                            ),
                        new Footer(style: Footer.Light, showSocials: false)
                    }
                                               )
                                           )
                                       )
                                   )
                               ));
                }
Beispiel #14
0
        Widget _buildInputField()
        {
            var imageName = $"{CImageUtils.FavoriteCoverImagePath}/{this._favoriteImageName}";

            return(new Container(
                       padding: EdgeInsets.all(16),
                       color: CColors.White,
                       child: new Column(
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: new List <Widget> {
                new Row(
                    children: new List <Widget> {
                    new FavoriteTagCoverImage(
                        coverImage: imageName,
                        new Color(value: this._favoriteImageColor),
                        margin: EdgeInsets.only(right: 16)
                        ),
                    new Expanded(
                        child: new InputField(
                            focusNode: this._nameFocusNode,
                            height: 48,
                            controller: this._nameController,
                            maxLength: _nameMaxLength,
                            style: new TextStyle(
                                height: 1.2f,
                                fontSize: 18,
                                fontFamily: "Roboto-Medium",
                                color: CColors.TextBody2
                                ),
                            hintText: "收藏夹标题",
                            hintStyle: new TextStyle(
                                fontSize: 18,
                                fontFamily: "Roboto-Medium",
                                color: CColors.TextBody4
                                ),
                            cursorColor: CColors.PrimaryBlue,
                            clearButtonMode: InputFieldClearButtonMode.never,
                            onChanged: text => {
                        this.setState(() => this._favoriteName = text);
                        this._setEnableSubmit();
                    }
                            )
                        ),
                    new Text(
                        $"{_nameMaxLength - this._favoriteName.Length}",
                        style: new TextStyle(
                            fontSize: 12,
                            fontFamily: "Roboto-Regular",
                            color: CColors.ShadyLady
                            )
                        )
                }
                    ),
                new Container(
                    margin: EdgeInsets.only(top: 16),
                    child: new Stack(
                        children: new List <Widget> {
                    new InputField(
                        focusNode: this._descriptionFocusNode,
                        height: 120,
                        controller: this._descriptionController,
                        maxLength: _descriptionMaxLength,
                        maxLines: null,
                        alignment: Alignment.topLeft,
                        style: CTextStyle.PLargeBody2,
                        hintText: "描述一下这个收藏夹…",
                        hintStyle: CTextStyle.PLargeBody4,
                        cursorColor: CColors.PrimaryBlue,
                        clearButtonMode: InputFieldClearButtonMode.never,
                        onChanged: text => {
                        this.setState(() => this._favoriteDescription = text);
                        this._setEnableSubmit();
                    }
                        ),
                    new Positioned(
                        right: 0,
                        bottom: 0,
                        child: new Text(
                            $"{_descriptionMaxLength - this._favoriteDescription.Length}",
                            style: new TextStyle(
                                fontSize: 12,
                                fontFamily: "Roboto-Regular",
                                color: CColors.ShadyLady
                                )
                            )
                        )
                }
                        )
                    )
            }
                           )
                       ));
        }
Beispiel #15
0
        Widget _buildChatBar(bool showChatWindow)
        {
            IconData iconData;
            Widget   bottomWidget;

            if (showChatWindow)
            {
                iconData     = Icons.expand_more;
                bottomWidget = new Container();
            }
            else
            {
                iconData     = Icons.expand_less;
                bottomWidget = new Text(
                    "轻点展开聊天",
                    style: CTextStyle.PSmallBody4
                    );
            }

            return(new GestureDetector(
                       onTap: () => {
                this._focusNode.unfocus();
                if (!showChatWindow)
                {
                    this._controller.forward();
                }
                else
                {
                    this._controller.reverse();
                }

                this.widget.actionModel.showChatWindow(!this.widget.viewModel.showChatWindow);
            },
                       child: new Container(
                           padding: EdgeInsets.symmetric(horizontal: 16),
                           color: CColors.White,
                           height: showChatWindow ? 44 : 64,
                           child: new Row(
                               mainAxisAlignment: MainAxisAlignment.spaceBetween,
                               children: new List <Widget> {
                new Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: new List <Widget> {
                    new Row(
                        children: new List <Widget> {
                        new Container(
                            margin: EdgeInsets.only(right: 6),
                            width: 6,
                            height: 6,
                            decoration: new BoxDecoration(
                                CColors.SecondaryPink,
                                borderRadius: BorderRadius.circular(3)
                                )
                            ),
                        new Text(
                            "直播聊天",
                            style: new TextStyle(
                                height: 1.09f,
                                fontSize: 16,
                                fontFamily: "Roboto-Medium",
                                color: CColors.TextBody
                                )
                            )
                    }
                        ),
                    bottomWidget
                }
                    ),
                new Icon(
                    iconData,
                    color: CColors.BrownGrey,
                    size: 28
                    )
            }
                               )
                           )
                       ));
        }
        Widget _buildSwiper()
        {
            var homeSliderIds = this.widget.viewModel.homeSliderIds;

            if (homeSliderIds.isNullOrEmpty())
            {
                return(new Container());
            }

            Widget swiperContent;

            if (homeSliderIds.Count == 1)
            {
                var homeSliderId = homeSliderIds[0];
                var imageUrl     = this.widget.viewModel.rankDict.ContainsKey(key: homeSliderId)
                    ? this.widget.viewModel.rankDict[key : homeSliderId].image
                                   : "";
                swiperContent = new GestureDetector(
                    onTap: () => {
                    var redirectURL = this.widget.viewModel.rankDict.ContainsKey(key: homeSliderId)
                            ? this.widget.viewModel.rankDict[key: homeSliderId].redirectURL
                            : "";
                    if (redirectURL.isNotEmpty())
                    {
                        this.widget.actionModel.openUrl(obj: redirectURL);
                    }
                },
                    child: new PlaceholderImage(
                        imageUrl: imageUrl,
                        fit: BoxFit.fill,
                        useCachedNetworkImage: true,
                        color: CColorUtils.GetSpecificDarkColorFromId(id: homeSliderId)
                        )
                    );
            }
            else
            {
                swiperContent = new Swiper(
                    (cxt, index) => {
                    var homeSliderId = homeSliderIds[index: index];
                    var imageUrl     = this.widget.viewModel.rankDict.ContainsKey(key: homeSliderId)
                            ? this.widget.viewModel.rankDict[key: homeSliderId].image
                            : "";
                    return(new PlaceholderImage(
                               CImageUtils.SizeToScreenImageUrl(imageUrl: imageUrl),
                               fit: BoxFit.fill,
                               useCachedNetworkImage: true,
                               color: CColorUtils.GetSpecificDarkColorFromId(id: homeSliderId)
                               ));
                },
                    itemCount: homeSliderIds.Count,
                    autoplay: true,
                    onTap: index => {
                    var homeSliderId = homeSliderIds[index: index];
                    var redirectURL  = this.widget.viewModel.rankDict.ContainsKey(key: homeSliderId)
                            ? this.widget.viewModel.rankDict[key: homeSliderId].redirectURL
                            : "";
                    if (redirectURL.isNotEmpty())
                    {
                        this.widget.actionModel.openUrl(obj: redirectURL);
                    }
                },
                    pagination: new SwiperPagination(margin: EdgeInsets.only(bottom: 5))
                    );
            }

            return(new Container(
                       padding: EdgeInsets.only(top: 8, left: 16, right: 16),
                       decoration: new BoxDecoration(
                           borderRadius: BorderRadius.all(8),
                           color: CColors.White
                           ),
                       child: new AspectRatio(
                           aspectRatio: 3,
                           child: new ClipRRect(
                               borderRadius: BorderRadius.all(8),
                               child: swiperContent
                               )
                           )
                       ));
        }
Beispiel #17
0
        Widget _buildChatList()
        {
            Widget child = new Container();

            if (this.widget.viewModel.messageLoading)
            {
                child = new GlobalLoading();
            }
            else
            {
                if (this.widget.viewModel.messageList.Count <= 0)
                {
                    child = new BlankView("暂无聊天内容", null);
                }
                else
                {
                    child = new SmartRefresher(
                        controller: this._refreshController,
                        enablePullDown: this.widget.viewModel.hasMore,
                        enablePullUp: false,
                        onRefresh: this._onRefresh,
                        child: ListView.builder(
                            padding: EdgeInsets.only(16, right: 16, bottom: 10),
                            physics: new AlwaysScrollableScrollPhysics(),
                            itemCount: this.widget.viewModel.messageList.Count,
                            itemBuilder: (cxt, index) => {
                        var messageId =
                            this.widget.viewModel.messageList[
                                this.widget.viewModel.messageList.Count - index - 1];
                        var messageDict = new Dictionary <string, Message>();
                        if (this.widget.viewModel.channelMessageDict.ContainsKey(
                                this.widget.viewModel.channelId))
                        {
                            messageDict =
                                this.widget.viewModel.channelMessageDict[this.widget.viewModel.channelId];
                        }

                        var message = new Message();
                        if (messageDict.ContainsKey(messageId))
                        {
                            message = messageDict[messageId];
                        }

                        return(new ChatMessage(
                                   message
                                   ));
                    }
                            )
                        );
                }
            }

            return(new Flexible(
                       child: new GestureDetector(
                           onTap: () => this._focusNode.unfocus(),
                           child: new Container(
                               color: CColors.White,
                               child: child
                               )
                           )
                       ));
        }
        Widget _buildTopView()
        {
            Widget leftWidget;

            switch (this.widget.viewModel.fromPage)
            {
            case FromPage.login: {
                leftWidget = new CustomButton(
                    onPressed: () => this.widget.actionModel.loginRouterPop(),
                    child: new Icon(
                        icon: Icons.arrow_back,
                        size: 24,
                        color: CColors.Icon
                        )
                    );
                break;
            }

            case FromPage.wechat: {
                leftWidget = new CustomButton(
                    onPressed: () => this.widget.actionModel.mainRouterPop(),
                    child: new Text(
                        "跳过",
                        style: CTextStyle.PLargeBody4
                        )
                    );
                break;
            }

            case FromPage.setting: {
                leftWidget = new CustomButton(
                    onPressed: () => this.widget.actionModel.mainRouterPop(),
                    child: new Icon(
                        icon: Icons.arrow_back,
                        size: 24,
                        color: CColors.Icon
                        )
                    );
                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(new Column(
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: new List <Widget> {
                new Container(
                    height: 44,
                    padding: EdgeInsets.only(8, 8, 8),
                    child: new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: new List <Widget> {
                    leftWidget,
                    new CustomButton(
                        onPressed: () => this.widget.actionModel.openCreateUnityIdUrl(),
                        child: new Text(
                            "创建 Unity ID",
                            style: CTextStyle.PLargeMediumBlue
                            )
                        )
                }
                        )
                    ),
                new Container(height: 16),
                new Container(
                    padding: EdgeInsets.symmetric(horizontal: 16),
                    child: new Text(
                        this.widget.viewModel.fromPage == FromPage.login ? "登录你的Unity账号" : "绑定你的Unity账号",
                        style: CTextStyle.H2
                        )
                    )
            }
                       ));
        }
Beispiel #19
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);
        }
 Widget _buildMiddleView(BuildContext context)
 {
     return(new Container(
                padding: EdgeInsets.symmetric(horizontal: 16),
                child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: new List <Widget> {
         new Container(height: 32),
         new Container(
             child: new Text(
                 "邮箱",
                 style: CTextStyle.PMediumBody4
                 )
             ),
         new Container(
             height: 46,
             decoration: new BoxDecoration(
                 CColors.Transparent,
                 border: new Border(
                     bottom: new BorderSide(
                         this._isEmailFocus ? CColors.PrimaryBlue : CColors.Separator,
                         this._isEmailFocus ? 2 : 1
                         )
                     )
                 ),
             alignment: Alignment.center,
             child: new InputField(
                 focusNode: this._emailFocusNode,
                 maxLines: 1,
                 autofocus: true,
                 enabled: !this.widget.viewModel.loginLoading,
                 style: CTextStyle.PLargeBody,
                 cursorColor: CColors.PrimaryBlue,
                 clearButtonMode: InputFieldClearButtonMode.whileEditing,
                 keyboardType: TextInputType.emailAddress,
                 onChanged: text => this.widget.actionModel.changeEmail(text),
                 onSubmitted: _ => {
             if (null == this._focusScopeNode)
             {
                 this._focusScopeNode = FocusScope.of(context);
             }
             this._focusScopeNode.requestFocus(this._passwordFocusNode);
         }
                 )
             ),
         new Container(height: 16),
         new Container(
             child: new Text(
                 "密码",
                 style: CTextStyle.PMediumBody4
                 )
             ),
         new Container(
             height: 46,
             decoration: new BoxDecoration(
                 CColors.Transparent,
                 border: new Border(
                     bottom: new BorderSide(
                         this._isPasswordFocus ? CColors.PrimaryBlue : CColors.Separator,
                         this._isPasswordFocus ? 2 : 1
                         )
                     )
                 ),
             alignment: Alignment.center,
             child: new InputField(
                 focusNode: this._passwordFocusNode,
                 maxLines: 1,
                 autofocus: false,
                 obscureText: true,
                 enabled: !this.widget.viewModel.loginLoading,
                 style: CTextStyle.PLargeBody,
                 cursorColor: CColors.PrimaryBlue,
                 clearButtonMode: InputFieldClearButtonMode.whileEditing,
                 onChanged: text => this.widget.actionModel.changePassword(text),
                 onSubmitted: _ => this._login()
                 )
             )
     }
                    )
                ));
 }
Beispiel #21
0
 public static Widget SettingValueUpDownButton(string title, string value, VoidCallback upPressed = null, VoidCallback downPressed = null, string upButtonText = "+", string downButtontext = "-")
 {
     return(new Container(
                padding: EdgeInsets.symmetric(horizontal: 6f),
                child: new Row(
                    children: new List <Widget>
     {
         new Container(
             child: new Text(title)
             ),
         new Expanded(
             child: new Row(
                 mainAxisAlignment: Unity.UIWidgets.rendering.MainAxisAlignment.end,
                 children: new List <Widget>
         {
             new Container(
                 width: 40,
                 child: new RaisedButton(
                     padding: EdgeInsets.zero,
                     child:  new Text(downButtontext),
                     color: Colors.white,
                     shape: new CircleBorder(
                         side: new BorderSide(
                             color:  Colors.grey,
                             width:  1,
                             style:  BorderStyle.solid
                             )         //BorderSide
                         ),            //CircleBorder
                     onPressed:  () => {
                 downPressed?.Invoke();
             }
                     )
                 ),            //RaisedButton
             new Container(
                 padding: EdgeInsets.symmetric(horizontal: 16f),
                 alignment: Alignment.center,
                 child: new Text(value.ToString())
                 ),
             new Container(
                 width: 40,
                 child: new RaisedButton(
                     padding: EdgeInsets.zero,
                     child:  new Text(upButtonText),
                     color: Colors.white,
                     shape: new CircleBorder(
                         side: new BorderSide(
                             color:  Colors.grey,
                             width:  1,
                             style:  BorderStyle.solid
                             )         //BorderSide
                         ),            //CircleBorder
                     onPressed:  () => {
                 upPressed?.Invoke();
             }
                     ) //RaisedButton
                 )     //Container
         }
                 )     //Container
             )         //Expand
     }                 //list
                    )  //row
                ));
 }
        Widget _buildBottomView()
        {
            Widget right;

            if (this.widget.viewModel.loginLoading)
            {
                right = new CustomActivityIndicator(
                    loadingColor: LoadingColor.white,
                    size: LoadingSize.small
                    );
            }
            else
            {
                right = new Container();
            }

            return(new Container(
                       padding: EdgeInsets.symmetric(horizontal: 16),
                       child: new Column(
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: new List <Widget> {
                new Container(height: 32),
                new CustomButton(
                    onPressed: this._login,
                    padding: EdgeInsets.zero,
                    child: new Container(
                        height: 48,
                        decoration: new BoxDecoration(this.widget.viewModel.loginBtnEnable
                                        ? this.widget.viewModel.loginLoading
                                            ? CColors.ButtonActive
                                            : CColors.PrimaryBlue
                                        : CColors.Disable,
                                                      borderRadius: BorderRadius.all(24)
                                                      ),
                        child: new Stack(
                            children: new List <Widget> {
                    new Align(
                        alignment: Alignment.center,
                        child: new Text(
                            "确定",
                            maxLines: 1,
                            style: CTextStyle.PLargeWhite
                            )
                        ),
                    new Positioned(
                        right: 24,
                        height: 48,
                        child: right
                        )
                }
                            )
                        )
                    ),
                new Container(height: 8),
                new CustomButton(
                    onPressed: () => this.widget.actionModel.openUrl($"{Config.idBaseUrl}/password/new"),
                    child: new Text(
                        "忘记密码",
                        style: CTextStyle.PRegularBody3
                        )
                    )
            }
                           )
                       ));
        }
Beispiel #23
0
        public static Widget SettingBlockColorPicker(
            BuildContext context,
            string title,
            ValueChanged <Color> onColorChanged,
            Color color                  = null,
            string buttonName            = "",
            List <Color> availableColors = null
            )
        {
            if (color == null)
            {
                color = Colors.blueAccent;
            }
            if (buttonName == "")
            {
                buttonName = color.ToHexString(false);
            }
            if (availableColors == null)
            {
                availableColors = Utils._defaultColors;
            }

            return(new Container(
                       padding: EdgeInsets.symmetric(horizontal: 6f),
                       child: new Row(
                           children: new List <Widget>
            {
                new Container(child: new Text(title)),
                new Expanded(
                    child: new Container(
                        padding: EdgeInsets.all(6),
                        alignment: Alignment.bottomRight,
                        child:  new RaisedButton(
                            color: color,
                            child: new Text(
                                buttonName,
                                style: new TextStyle(
                                    color: Utils.useWhiteForeground(color) ? Colors.white : Colors.black
                                    ) //TextStyle
                                ),    //Text
                            onPressed: () => {
                    DialogUtils.showDialog(
                        context: context,
                        builder: (BuildContext _) => {
                        return new AlertDialog(
                            title: new Text("Select color"),
                            content: new SingleChildScrollView(
                                child: new BlockPicker(
                                    pickerColor: color,
                                    onColorChanged: onColorChanged,
                                    availableColors: availableColors
                                    )     //BlockPicker
                                )         //SingleChildScrollView
                            );            //AlertDialog
                    }
                        );                //showDialog
                }
                            )
                        )    //container
                    ),       //expanded
            }                //list
                           ) //row
                       ));
        }
Beispiel #24
0
        public override Widget build(BuildContext context)
        {
            Orientation?orientation = MediaQuery.of(context).orientation;

            return(new Scaffold(
                       appBar: new AppBar(
                           title: new Text("Grid list"),
                           actions: new List <Widget>
            {
                new MaterialDemoDocumentationButton(GridListDemo.routeName),
                new PopupMenuButton <GridDemoTileStyle>(
                    onSelected: changeTileStyle,
                    itemBuilder: (BuildContext subContext) => new List <PopupMenuEntry <GridDemoTileStyle> >
                {
                    new PopupMenuItem <GridDemoTileStyle>(
                        value: GridDemoTileStyle.imageOnly,
                        child: new Text("Image only")
                        ),
                    new PopupMenuItem <GridDemoTileStyle>(
                        value: GridDemoTileStyle.oneLine,
                        child: new Text("One line")
                        ),
                    new PopupMenuItem <GridDemoTileStyle>(
                        value: GridDemoTileStyle.twoLine,
                        child: new Text("Two line")
                        )
                }
                    )
            }
                           ),
                       body: new Column(
                           children: new List <Widget>
            {
                new Expanded(
                    child: new SafeArea(
                        top: false,
                        bottom: false,
                        child: GridView.count(
                            crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3,
                            mainAxisSpacing: 4.0f,
                            crossAxisSpacing: 4.0f,
                            padding: EdgeInsets.all(4.0f),
                            childAspectRatio: (orientation == Orientation.portrait) ? 1.0f : 1.3f,
                            children: photos.Select <Photo, Widget>((Photo photo) =>
                {
                    return new GridDemoPhotoItem(
                        photo: photo,
                        tileStyle: _tileStyle,
                        onBannerTap: (Photo curPhoto) =>
                    {
                        setState(() => { curPhoto.isFavorite = !curPhoto.isFavorite; });
                    }
                        );
                }).ToList()
                            )
                        )
                    )
            }
                           )
                       ));
        }
Beispiel #25
0
 public override Widget build(BuildContext context)
 {
     return(new DividerTheme(
                data: new DividerThemeData(
                    ),
                child: new Container(
                    height: 200,
                    padding: EdgeInsets.all(10),
                    decoration: new BoxDecoration(
                        color: new Color(0xFFEF1F7F),
                        border: Border.all(color: Color.fromARGB(255, 0xDF, 0x10, 0x70), width: 5),
                        borderRadius: BorderRadius.all(20)
                        ),
                    child: new Center(
                        child: new Column(
                            children: new List <Widget>()
     {
         new Text(this.title),
         new Divider(),
         new Text(this.subtitle),
         new Divider(),
         new Container(
             width: 500,
             decoration: new BoxDecoration(border: Border.all(new Color(0xFF00FF00), 1)),
             child: new EditableText(
                 controller: this.controller,
                 focusNode: new FocusNode(),
                 style: new TextStyle(
                     fontSize: 18,
                     height: 1.5f,
                     color: new Color(0xFFFF89FD)),
                 cursorColor: Color.fromARGB(255, 0, 0, 0),
                 backgroundCursorColor: Colors.grey
                 )
             ),
         new Divider(),
         new ButtonBar(
             children: new List <Widget> {
             new FlatButton(
                 onPressed: () => {
                 this.setState(() => { this.title = this.controller.text; });
             },
                 padding: EdgeInsets.all(5.0f),
                 child: new Center(
                     child: new Text("Set Title")
                     )
                 ),
             new RaisedButton(
                 onPressed: () => {
                 this.setState(() => { this.subtitle = this.controller.text; });
             },
                 padding: EdgeInsets.all(5.0f),
                 child: new Center(
                     child: new Text("Set Subtitle")
                     )
                 )
         }
             )
     }
                            )
                        )
                    )));
 }
Beispiel #26
0
        Widget _buildHeadTop(bool isShowTitle, IEvent eventObj)
        {
            Widget shareWidget = new CustomButton(
                onPressed: () => this._showShareView(eventObj),
                child: new Container(
                    color: CColors.Transparent,
                    child: new Icon(Icons.share, size: 28,
                                    color: this._showNavBarShadow ? CColors.White : CColors.Icon))
                );
            Widget titleWidget = new Container();

            if (isShowTitle)
            {
                Widget child = new Container();
                if (this._isHaveTitle)
                {
                    child = new Text(
                        eventObj.title,
                        style: CTextStyle.PXLargeMedium,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        textAlign: TextAlign.center
                        );
                }

                titleWidget = new Expanded(
                    child: new Stack(
                        fit: StackFit.expand,
                        children: new List <Widget> {
                    new PositionedTransition(
                        rect: this._titleAnimation,
                        child: child
                        )
                }
                        )
                    );
            }

            return(new AnimatedContainer(
                       height: 44,
                       duration: TimeSpan.FromSeconds(0),
                       padding: EdgeInsets.symmetric(horizontal: 8),
                       decoration: new BoxDecoration(
                           CColors.White,
                           border: new Border(
                               bottom: new BorderSide(this._isHaveTitle ? CColors.Separator2 : CColors.Transparent)),
                           gradient: this._showNavBarShadow
                        ? new LinearGradient(
                               colors: new List <Color> {
                new Color(0x80000000),
                new Color(0x0)
            },
                               begin: Alignment.topCenter,
                               end: Alignment.bottomCenter
                               )
                        : null
                           ),
                       child: new Row(
                           mainAxisAlignment: MainAxisAlignment.spaceBetween,
                           children: new List <Widget> {
                new CustomButton(
                    onPressed: () => { this.widget.actionModel.mainRouterPop(); },
                    child: new Icon(
                        Icons.arrow_back,
                        size: 28,
                        color: this._showNavBarShadow ? CColors.White : CColors.Icon
                        )
                    ),
                titleWidget,
                shareWidget
            }
                           )
                       ));
        }
Beispiel #27
0
        public override Widget build(BuildContext context)
        {
            D.assert(MaterialD.debugCheckHasMaterial(context));
            D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));

            List <Widget> items     = this._enabled ? new List <Widget>(this.widget.items) : new List <Widget>();
            int           hintIndex = 0;

            if (this.widget.hint != null || (!this._enabled && this.widget.disabledHint != null))
            {
                Widget emplacedHint =
                    this._enabled
                        ? this.widget.hint
                        : new DropdownMenuItem <Widget>(child: this.widget.disabledHint ?? this.widget.hint);
                hintIndex = items.Count;
                items.Add(new DefaultTextStyle(
                              style: this._textStyle.copyWith(color: Theme.of(context).hintColor),
                              child: new IgnorePointer(
                                  child: emplacedHint
                                  )
                              ));
            }

            EdgeInsets padding = ButtonTheme.of(context).alignedDropdown
                ? DropdownConstants._kAlignedButtonPadding
                : DropdownConstants._kUnalignedButtonPadding;

            IndexedStack innerItemsWidget = new IndexedStack(
                index: this._enabled ? (this._selectedIndex ?? hintIndex) : hintIndex,
                alignment: Alignment.centerLeft,
                children: items
                );

            Icon   defaultIcon = new Icon(Icons.arrow_drop_down);
            Widget result      = new DefaultTextStyle(
                style: this._textStyle,
                child: new Container(
                    padding: padding,
                    height: this.widget.isDense ? this._denseButtonHeight : null,
                    child: new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        mainAxisSize: MainAxisSize.min,
                        children: new List <Widget> {
                this.widget.isExpanded ? new Expanded(child: innerItemsWidget) : (Widget)innerItemsWidget,
                new IconTheme(
                    data: new IconThemeData(
                        color: this._iconColor,
                        size: this.widget.iconSize
                        ),
                    child: this.widget.icon ?? defaultIcon
                    )
            }
                        )
                    )
                );

            if (!DropdownButtonHideUnderline.at(context))
            {
                float bottom = this.widget.isDense ? 0.0f : 8.0f;
                result = new Stack(
                    children: new List <Widget> {
                    result,
                    new Positioned(
                        left: 0.0f,
                        right: 0.0f,
                        bottom: bottom,
                        child: this.widget.underline ?? new Container(
                            height: 1.0f,
                            decoration: new BoxDecoration(
                                border: new Border(
                                    bottom: new BorderSide(color: new Color(0xFFBDBDBD), width: 0.0f))
                                )
                            )
                        )
                }
                    );
            }

            return(new GestureDetector(
                       onTap: this._enabled ? (GestureTapCallback)this._handleTap : null,
                       behavior: HitTestBehavior.opaque,
                       child: result
                       ));
        }
Beispiel #28
0
        Widget _buildEventBottom(IEvent eventObj, EventType eventType, EventStatus eventStatus,
                                 bool isLoggedIn)
        {
            if (eventStatus != EventStatus.future && eventType == EventType.online && isLoggedIn)
            {
                return(new Container());
            }

            var onlineCount      = eventObj.onlineMemberCount;
            var recordWatchCount = eventObj.recordWatchCount;
            var userIsCheckedIn  = eventObj.userIsCheckedIn;
            var title            = "";
            var subTitle         = "";

            if (eventStatus == EventStatus.live)
            {
                title    = "正在直播";
                subTitle = $"{onlineCount}人正在观看";
            }

            if (eventStatus == EventStatus.past)
            {
                title    = "回放";
                subTitle = $"{recordWatchCount}次观看";
            }

            if (eventStatus == EventStatus.future || eventStatus == EventStatus.countDown)
            {
                var begin     = eventObj.begin != null ? eventObj.begin : new TimeMap();
                var startTime = begin.startTime;
                if (startTime.isNotEmpty())
                {
                    subTitle = DateConvert.GetFutureTimeFromNow(startTime);
                }

                title = "距离开始还有";
            }

            var backgroundColor = CColors.PrimaryBlue;
            var joinInText      = "立即加入";
            var textStyle       = CTextStyle.PLargeMediumWhite;

            if (userIsCheckedIn && isLoggedIn)
            {
                backgroundColor = CColors.Disable;
                joinInText      = "已加入";
                textStyle       = CTextStyle.PLargeMediumWhite;
            }

            Widget child = new Text(
                joinInText,
                style: textStyle
                );

            if (this.widget.viewModel.joinEventLoading)
            {
                child = new CustomActivityIndicator(
                    loadingColor: LoadingColor.white
                    );
            }

            return(new Container(
                       height: 64,
                       padding: EdgeInsets.symmetric(horizontal: 16),
                       decoration: new BoxDecoration(
                           CColors.White,
                           border: new Border(new BorderSide(CColors.Separator))
                           ),
                       child: new Row(
                           mainAxisAlignment: MainAxisAlignment.spaceBetween,
                           children: new List <Widget> {
                new Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: new List <Widget> {
                    new Text(
                        title,
                        style: CTextStyle.PSmallBody4
                        ),
                    new Container(height: 2),
                    new Text(
                        subTitle,
                        style: CTextStyle.H5Body
                        )
                }
                    ),
                new CustomButton(
                    onPressed: () => {
                    if (this.widget.viewModel.joinEventLoading)
                    {
                        return;
                    }

                    if (!this.widget.viewModel.isLoggedIn)
                    {
                        this.widget.actionModel.pushToLogin();
                    }
                    else
                    {
                        if (!userIsCheckedIn)
                        {
                            this.widget.actionModel.startJoinEvent();
                            this.widget.actionModel.joinEvent(this.widget.viewModel.eventId);
                        }
                    }
                },
                    child: new Container(
                        width: 96,
                        height: 40,
                        decoration: new BoxDecoration(
                            backgroundColor,
                            borderRadius: BorderRadius.all(4)
                            ),
                        alignment: Alignment.center,
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: new List <Widget> {
                    child
                }
                            )
                        )
                    )
            }
                           )
                       ));
        }
Beispiel #29
0
        public override Widget build(BuildContext context)
        {
            if (this.model == null)
            {
                return(new Container());
            }

            var time       = Convert.ToDateTime(this.model.begin.startTime);
            var hour       = $"{time.Hour.ToString().PadLeft(2, '0')}";
            var minute     = $"{time.Minute.ToString().PadLeft(2, '0')}";
            var hourMinute = $"{hour}:{minute}";
            var address    = this.place ?? "";
            var imageUrl   = this.model.avatar ?? this.model.background;
            var card       = new Container(
                padding: EdgeInsets.all(16),
                color: CColors.White,
                child: new Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: new List <Widget> {
                new Container(
                    width: 32,
                    margin: EdgeInsets.only(right: 10),
                    child: new Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: new List <Widget> {
                    new Text(
                        time.Day.ToString(),
                        style: new TextStyle(
                            height: 1.33f,
                            fontSize: 24,
                            fontFamily: "Roboto-Bold",
                            color: CColors.SecondaryPink
                            )
                        ),
                    new Text(
                        $"{time.Month.ToString()}月",
                        style: CTextStyle.CaptionBody
                        )
                }
                        )
                    ),
                new Expanded(
                    child: new Container(
                        margin: EdgeInsets.only(right: 8),
                        child: new Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: new List <Widget> {
                    new Container(
                        margin: EdgeInsets.only(bottom: 8),
                        child: new Text(this.model.title,
                                        style: CTextStyle.PLargeMedium,
                                        maxLines: 2,
                                        overflow: TextOverflow.ellipsis
                                        )
                        ),
                    new Text(this.model.mode == "online"
                                                ? $"{hourMinute} · {this.model.participantsCount}人已预订"
                                                : $"{hourMinute}  · {address}",
                             style: CTextStyle.PSmallBody3
                             )
                }
                            )
                        )
                    ),
                new Container(
                    width: 114,
                    height: 76,
                    child: new Stack(
                        children: new List <Widget> {
                    new PlaceholderImage(
                        imageUrl.EndsWith(".gif") ? imageUrl : $"{imageUrl}.600x0x1.jpg",
                        114,
                        76,
                        4,
                        BoxFit.cover
                        ),
                    new Positioned(
                        bottom: 0,
                        right: 0,
                        child: new ClipRRect(
                            borderRadius: BorderRadius.only(bottomRight: 4),
                            child: new Container(
                                width: 41,
                                height: 24,
                                color: this.model.mode == "online"
                                                    ? CColors.SecondaryPink
                                                    : CColors.PrimaryBlue,
                                alignment: Alignment.center,
                                child: new Text(this.model.mode == "online" ? "线上" : "线下",
                                                style: CTextStyle.CaptionWhite,
                                                textAlign: TextAlign.center
                                                )
                                )
                            )
                        )
                }
                        )
                    )
            }
                    )
                );

            return(new GestureDetector(
                       child: card,
                       onTap: this.onTap
                       ));
        }
        IEnumerable <Widget> _buildComments(BuildContext context)
        {
            List <string> channelComments = new List <string>();

            if (this.widget.viewModel.channelMessageList.ContainsKey(key: this._article.channelId))
            {
                channelComments = this.widget.viewModel.channelMessageList[key : this._article.channelId];
            }

            var mediaQuery = MediaQuery.of(context);
            var comments   = new List <Widget> {
                new Container(
                    color: CColors.White,
                    width: mediaQuery.size.width,
                    padding: EdgeInsets.only(16, 16, 16),
                    child: new Text(
                        "评论",
                        style: CTextStyle.H5,
                        textAlign: TextAlign.left
                        )
                    )
            };

            var titleHeight = CTextUtils.CalculateTextHeight(
                "评论",
                CTextStyle.H5,
                mediaQuery.size.width - 16 * 2 // 16 is horizontal padding
                ) + 16;                        // 16 is top padding

            float safeAreaPadding = 0;

            if (Application.platform != RuntimePlatform.Android)
            {
                safeAreaPadding = mediaQuery.padding.vertical;
            }

            var height = mediaQuery.size.height - navBarHeight - 44 - safeAreaPadding;

            if (channelComments.Count == 0)
            {
                var blankView = new Container(
                    height: height - titleHeight,
                    child: new BlankView(
                        "快来写下第一条评论吧",
                        "image/default-comment"
                        )
                    );
                comments.Add(item: blankView);
                return(comments);
            }

            var   messageDict    = this.widget.viewModel.channelMessageDict[key : this._article.channelId];
            float contentHeights = 0;

            foreach (var commentId in channelComments)
            {
                if (!messageDict.ContainsKey(key: commentId))
                {
                    break;
                }

                var message     = messageDict[key : commentId];
                var userLicense = CCommonUtils.GetUserLicense(userId: message.author.id,
                                                              userLicenseMap: this.widget.viewModel.userLicenseDict);
                bool isPraised      = _isPraised(message: message, loginUserId: this.widget.viewModel.loginUserId);
                var  parentName     = "";
                var  parentAuthorId = "";
                if (message.upperMessageId.isNotEmpty())
                {
                    if (messageDict.ContainsKey(key: message.upperMessageId))
                    {
                        var parentMessage = messageDict[key : message.upperMessageId];
                        parentName     = parentMessage.author.fullName;
                        parentAuthorId = parentMessage.author.id;
                    }
                }
                else if (message.parentMessageId.isNotEmpty())
                {
                    if (messageDict.ContainsKey(key: message.parentMessageId))
                    {
                        var parentMessage = messageDict[key : message.parentMessageId];
                        parentName     = parentMessage.author.fullName;
                        parentAuthorId = parentMessage.author.id;
                    }
                }

                var content = MessageUtils.AnalyzeMessage(message.content, message.mentions,
                                                          message.mentionEveryone) + (parentName.isEmpty() ? "" : $"回复@{parentName}");
                var contentHeight = CTextUtils.CalculateTextHeight(
                    content,
                    CTextStyle.PLargeBody,
                    // 16 is horizontal padding, 24 is avatar size, 8 is content left margin to avatar
                    mediaQuery.size.width - 16 * 2 - 24 - 8
                    ) + 16 + 24 + 3 + 5 + 22 + 12;
                // 16 is top padding, 24 is avatar size, 3 is content top margin to avatar, 5 is content bottom margin to commentTime
                // 22 is commentTime height, 12 is commentTime bottom margin
                contentHeights += contentHeight;
                var card = new CommentCard(
                    message: message,
                    userLicense: userLicense,
                    isPraised: isPraised,
                    parentName: parentName,
                    parentAuthorId: parentAuthorId,
                    () => ReportManager.showReportView(
                        isLoggedIn: this.widget.viewModel.isLoggedIn,
                        reportType: ReportType.comment,
                        () => this.widget.actionModel.pushToLogin(),
                        () => this.widget.actionModel.pushToReport(arg1: commentId, arg2: ReportType.comment)
                        ),
                    replyCallBack: () => this._sendComment(
                        "Article_Comment",
                        message.parentMessageId.isNotEmpty() ? message.parentMessageId : commentId,
                        message.parentMessageId.isNotEmpty() ? commentId : "",
                        message.author.fullName.isEmpty() ? "" : message.author.fullName
                        ),
                    praiseCallBack: () => {
                    if (!this.widget.viewModel.isLoggedIn)
                    {
                        this.widget.actionModel.pushToLogin();
                    }
                    else
                    {
                        if (isPraised)
                        {
                            this.widget.actionModel.removeLikeComment(arg: message);
                        }
                        else
                        {
                            this.widget.actionModel.likeComment(arg: message);
                        }
                    }
                },
                    pushToUserDetail: this.widget.actionModel.pushToUserDetail
                    );
                comments.Add(item: card);
            }

            float endHeight = 0;

            if (!this._article.hasMore)
            {
                comments.Add(new EndView());
                endHeight = 52;
            }

            if (titleHeight + contentHeights + endHeight < height)
            {
                return(new List <Widget> {
                    new Container(
                        height: height,
                        child: new Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: comments
                            )
                        )
                });
            }

            return(comments);
        }