public static float CalculateTextHeight(string content, float width) { var contentHeight = CTextUtils.CalculateTextHeight(text: content, textStyle: _contentStyle, width - _contentPadding.horizontal); return(_contentPadding.vertical + contentHeight); }
public static float CalculateTextHeight(string content, float width) { var contentHeight = CTextUtils.CalculateTextHeight( text: MessageUtils.truncateMessage(content), textStyle: _contentStyle, textWidth: width - _contentPadding.horizontal); return(_contentPadding.vertical + contentHeight); }
public static float CalculateTextHeight(ChannelMessageView message, float width) { var attachment = message.attachments.first(); var fileTitleHeight = CTextUtils.CalculateTextHeight(text: attachment.filename, textStyle: _fileTitleStyle, width - _filePadding.horizontal - 42 - 16); var fileSizeHeight = CTextUtils.CalculateTextHeight(CStringUtils.FileSize(bytes: attachment.size), textStyle: _fileSizeStyle, width - _filePadding.horizontal - 42 - 16); return(_filePadding.vertical + fileTitleHeight + fileSizeHeight + 4); }
float _getTipMenuHeight(BuildContext context) { if (this.tipMenuItems == null || this.tipMenuItems.Count == 0) { return(0); } var width = MediaQuery.of(context: context).size.width; var textHeight = CTextUtils.CalculateTextHeight( this.tipMenuItems.FirstOrDefault()?.title ?? "", textStyle: CustomTextSelectionControlsUtils._kToolbarButtonFontStyle, textWidth: width, 1 ); return(textHeight + 20); }
public static float CalculateTextHeight(ChannelMessageView message, float width) { var contentHeight = CTextUtils.CalculateTextHeight( text: MessageUtils.truncateMessage(message.content), textStyle: _contentStyle, textWidth: width - _contentPadding.horizontal); float descriptionHeight; if (message.type == ChannelMessageType.embedImage) { descriptionHeight = ImageMessage.CalculateTextHeight(message: message); } else if (message.type == ChannelMessageType.embedExternal) { var embedData = message.embeds[0].embedData; var embedDataTitleHeight = CTextUtils.CalculateTextHeight(text: embedData.title, textStyle: _embedTitleStyle, width - 48); var embedDescriptionHeight = CTextUtils.CalculateTextHeight(text: embedData.description, textStyle: _embedDescriptionStyle, width - 48, 4); float embedNameHeight; if (embedData.image.isEmpty() && embedData.name.isEmpty()) { embedNameHeight = 0; } else { embedNameHeight = 22; } descriptionHeight = embedDataTitleHeight + 4 + embedDescriptionHeight + 4 + embedNameHeight; } else { descriptionHeight = 0; } return(contentHeight + descriptionHeight + _contentPadding.vertical + _contentPadding.vertical); }
public override Widget build(BuildContext context) { var children = new List <Widget>(); if (this.title.isNotEmpty()) { children.Add( new Container( padding: EdgeInsets.only(16, 24, 16, this.message == null ? 24 : 8), alignment: Alignment.center, child: new Text( data: this.title, style: CTextStyle.PLargeMedium, textAlign: TextAlign.center ) )); } if (this.message.isNotEmpty()) { var mediaQuery = MediaQuery.of(context: context); var horizontalPadding = mediaQuery.viewInsets.left + mediaQuery.viewInsets.right + 40 + 40; var width = mediaQuery.size.width - horizontalPadding - 32; var maxHeight = CTextUtils.CalculateTextHeight( text: this.message, textStyle: this._messageStyle, textWidth: width, 7); var totalHeight = CTextUtils.CalculateTextHeight( text: this.message, textStyle: this._messageStyle, textWidth: width); if (maxHeight < totalHeight) { maxHeight += 16; } else { maxHeight += 32; } children.Add(new Container( height: maxHeight, alignment: Alignment.center, child: new CustomScrollbar( new SingleChildScrollView( child: new Padding( padding: EdgeInsets.only(16, 8, 16, 16), child: new Text( data: this.message, style: this._messageStyle ) ) ) ) )); } if (this.actions != null) { children.Add(new CustomDivider( height: 1 )); var _children = new List <Widget>(); foreach (var _child in this.actions) { _children.Add(new Expanded( child: new Stack( fit: StackFit.expand, children: new List <Widget> { _child } ) )); var index = this.actions.IndexOf(_child); if (index < this.actions.Count - 1) { _children.Add(new Container( width: 1, color: CColors.Separator )); } } Widget child = new Container( height: 48, child: new Row( mainAxisAlignment: MainAxisAlignment.start, children: _children ) ); children.Add(item: child); } Widget dialogChild = new IntrinsicWidth( child: new Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: children ) ); return(new CustomDialog( backgroundColor: CColors.White, radius: 5, child: dialogChild )); }
IEnumerable <Widget> _buildComments(BuildContext context) { List <string> channelComments = new List <string>(); if (this.widget.viewModel.channelMessageList.ContainsKey(this._article.channelId)) { channelComments = this.widget.viewModel.channelMessageList[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 null ) + 16; // 16 is top padding var height = mediaQuery.size.height - navBarHeight - 44 - mediaQuery.padding.vertical; 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[this._article.channelId]; float contentHeights = 0; foreach (var commentId in channelComments) { if (!messageDict.ContainsKey(commentId)) { break; } var message = messageDict[commentId]; bool isPraised = _isPraised(message, this.widget.viewModel.loginUserId); var parentName = ""; if (message.parentMessageId.isNotEmpty()) { if (messageDict.ContainsKey(message.parentMessageId)) { var parentMessage = messageDict[message.parentMessageId]; parentName = parentMessage.author.fullName; } } 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, null ) + 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, isPraised, parentName, () => ReportManager.showReportView(this.widget.viewModel.isLoggedIn, commentId, ReportType.comment, this.widget.actionModel.pushToLogin, this.widget.actionModel.pushToReport ), replyCallBack: () => { if (!this.widget.viewModel.isLoggedIn) { this.widget.actionModel.pushToLogin(); } else { AnalyticsManager.ClickComment("Article_Comment", this._article.channelId, this._article.title, commentId); ActionSheetUtils.showModalActionSheet(new CustomInput( message.author.fullName.isEmpty() ? "" : message.author.fullName, text => { ActionSheetUtils.hiddenModalPopup(); this.widget.actionModel.sendComment(this._article.channelId, text, Snowflake.CreateNonce(), commentId ); }) ); } }, praiseCallBack: () => { if (!this.widget.viewModel.isLoggedIn) { this.widget.actionModel.pushToLogin(); } else { if (isPraised) { this.widget.actionModel.removeLikeComment(message); } else { this.widget.actionModel.likeComment(message); } } }); comments.Add(card); } float endHeight = 0; if (!this._article.hasMore) { comments.Add(new Container( height: 52, alignment: Alignment.center, child: new Text( "一 已经全部加载完毕 一", style: CTextStyle.PRegularBody4, textAlign: TextAlign.center ) )); 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); }
public override Widget build(BuildContext context) { this.widget.viewModel.articleDict.TryGetValue(this.widget.viewModel.articleId, out this._article); if (this.widget.viewModel.articleDetailLoading && (this._article == null || !this._article.isNotFirst)) { return(new Container( color: CColors.White, child: new CustomSafeArea( child: new Column( children: new List <Widget> { this._buildNavigationBar(false), new ArticleDetailLoading() } ) ) )); } if (this._article == null || this._article.channelId == null) { return(new Container()); } if (this._article.ownerType == "user") { if (this._article.userId != null && this.widget.viewModel.userDict.TryGetValue(this._article.userId, out this._user)) { this._user = this.widget.viewModel.userDict[this._article.userId]; } } if (this._article.ownerType == "team") { if (this._article.teamId != null && this.widget.viewModel.teamDict.TryGetValue(this._article.teamId, out this._team)) { this._team = this.widget.viewModel.teamDict[this._article.teamId]; } } if (this._titleHeight == 0f && this._article.title.isNotEmpty()) { this._titleHeight = CTextUtils.CalculateTextHeight( text: this._article.title, textStyle: CTextStyle.H3, MediaQuery.of(context).size.width - 16 * 2, // 16 is horizontal padding null ) + 16; // 16 is top padding this.setState(() => { }); } var commentIndex = 0; var originItems = this._article == null ? new List <Widget>() : this._buildItems(context, out commentIndex); commentIndex = this._jumpState == _ArticleJumpToCommentState.active ? commentIndex : 0; this._jumpState = _ArticleJumpToCommentState.Inactive; var child = new Container( color: CColors.Background, child: new Column( children: new List <Widget> { this._buildNavigationBar(), new Expanded( child: new CustomScrollbar( new CenteredRefresher( controller: this._refreshController, enablePullDown: false, enablePullUp: this._article.hasMore, onRefresh: this._onRefresh, onNotification: this._onNotification, children: originItems, centerIndex: commentIndex ) ) ), new ArticleTabBar(this._article.like, () => { if (!this.widget.viewModel.isLoggedIn) { this.widget.actionModel.pushToLogin(); } else { AnalyticsManager.ClickComment("Article", this._article.channelId, this._article.title); ActionSheetUtils.showModalActionSheet(new CustomInput( doneCallBack: text => { ActionSheetUtils.hiddenModalPopup(); this.widget.actionModel.sendComment(this._article.channelId, text, Snowflake.CreateNonce(), null ); }) ); } }, () => { if (!this.widget.viewModel.isLoggedIn) { this.widget.actionModel.pushToLogin(); } else { AnalyticsManager.ClickComment("Article", this._article.channelId, this._article.title); ActionSheetUtils.showModalActionSheet(new CustomInput( doneCallBack: text => { ActionSheetUtils.hiddenModalPopup(); this.widget.actionModel.sendComment(this._article.channelId, text, Snowflake.CreateNonce(), null ); }) ); } }, () => { if (!this.widget.viewModel.isLoggedIn) { this.widget.actionModel.pushToLogin(); } else { if (!this._article.like) { this.widget.actionModel.likeArticle(this._article.id); } } }, shareCallback: this.share ) } ) ); return(new Container( color: CColors.White, child: new CustomSafeArea( child: child ) )); }
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 null ) + 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]; 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, null ) + 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, 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); }
public override Widget build(BuildContext context) { this.widget.viewModel.articleDict.TryGetValue(key: this.widget.viewModel.articleId, value: out this._article); if (this.widget.viewModel.articleDetailLoading && (this._article == null || !this._article.isNotFirst)) { return(new Container( color: CColors.White, child: new CustomSafeArea( child: new Column( children: new List <Widget> { this._buildNavigationBar(false), new ArticleDetailLoading() } ) ) )); } if (this._article == null || this._article.channelId == null) { return(new Container( color: CColors.White, child: new CustomSafeArea( child: new Column( children: new List <Widget> { this._buildNavigationBar(false), new Flexible( child: new BlankView("帖子不存在", "image/default-history") ) } ) ) ));; } if (this._article.ownerType == "user") { if (this._article.userId != null && this.widget.viewModel.userDict.TryGetValue(this._article.userId, out this._user)) { this._user = this.widget.viewModel.userDict[key : this._article.userId]; } } if (this._article.ownerType == "team") { if (this._article.teamId != null && this.widget.viewModel.teamDict.TryGetValue(this._article.teamId, out this._team)) { this._team = this.widget.viewModel.teamDict[key : this._article.teamId]; } } if (this._titleHeight == 0f && this._article.title.isNotEmpty()) { this._titleHeight = CTextUtils.CalculateTextHeight( text: this._article.title, textStyle: CTextStyle.H3, MediaQuery.of(context).size.width - 16 * 2, // 16 is horizontal padding null ) + 16; // 16 is top padding this.setState(() => { }); } var commentIndex = 0; var originItems = this._article == null ? new List <Widget>() : this._buildItems(context, out commentIndex); commentIndex = this._jumpState == _ArticleJumpToCommentState.active ? commentIndex : 0; this._jumpState = _ArticleJumpToCommentState.Inactive; Widget contentWidget; //happens at the next frame after user presses the "Comment" button //we rebuild a CenteredRefresher so that we can calculate out the comment section's position if (this._needRebuildWithCachedCommentPosition == false && commentIndex != 0) { contentWidget = new CenteredRefresher( controller: this._refreshController, enablePullDown: false, enablePullUp: this._article.hasMore, onRefresh: this._onRefresh, onNotification: this._onNotification, children: originItems, centerIndex: commentIndex ); } else { //happens when the page is updated or (when _needRebuildWithCachedCommentPosition is true) at the next frame after //a CenteredRefresher is created and the comment section's position is estimated //we use 0 or this estimated position to initiate the SmartRefresher's init scroll offset, respectively D.assert(!this._needRebuildWithCachedCommentPosition || this._cachedCommentPosition != null); contentWidget = new SmartRefresher( initialOffset: this._needRebuildWithCachedCommentPosition ? this._cachedCommentPosition.Value : 0f, controller: this._refreshController, enablePullDown: false, enablePullUp: this._article.hasMore, onRefresh: this._onRefresh, onNotification: this._onNotification, child: ListView.builder( physics: new AlwaysScrollableScrollPhysics(), itemCount: originItems.Count, itemBuilder: (cxt, index) => originItems[index] )); if (this._needRebuildWithCachedCommentPosition) { this._needRebuildWithCachedCommentPosition = false; //assume that when we jump to the comment, the title should always be shown as the header //this assumption will fail when an article is shorter than 16 pixels in height (as referred to in _onNotification this._controller.forward(); this._isHaveTitle = true; } } var child = new Container( color: CColors.Background, child: new Column( children: new List <Widget> { this._buildNavigationBar(), new Expanded( child: new CustomScrollbar( child: contentWidget ) ), this._buildArticleTabBar() } ) ); return(new Container( color: CColors.White, child: new CustomSafeArea( child: child ) )); }
public override Widget build(BuildContext context) { this.widget.viewModel.articleDict.TryGetValue(key: this.widget.viewModel.articleId, value: out this._article); if (this.widget.viewModel.articleDetailLoading && (this._article == null || !this._article.isNotFirst)) { return(new Container( color: CColors.White, child: new CustomSafeArea( child: new Column( children: new List <Widget> { this._buildNavigationBar(false), new ArticleDetailLoading() } ) ) )); } if (this._article == null || this._article.channelId == null) { return(new Container()); } if (this._article.ownerType == "user") { if (this._article.userId != null && this.widget.viewModel.userDict.TryGetValue(this._article.userId, out this._user)) { this._user = this.widget.viewModel.userDict[key : this._article.userId]; } } if (this._article.ownerType == "team") { if (this._article.teamId != null && this.widget.viewModel.teamDict.TryGetValue(this._article.teamId, out this._team)) { this._team = this.widget.viewModel.teamDict[key : this._article.teamId]; } } if (this._titleHeight == 0f && this._article.title.isNotEmpty()) { this._titleHeight = CTextUtils.CalculateTextHeight( text: this._article.title, textStyle: CTextStyle.H3, MediaQuery.of(context).size.width - 16 * 2, // 16 is horizontal padding null ) + 16; // 16 is top padding this.setState(() => { }); } var commentIndex = 0; var originItems = this._article == null ? new List <Widget>() : this._buildItems(context, out commentIndex); commentIndex = this._jumpState == _ArticleJumpToCommentState.active ? commentIndex : 0; this._jumpState = _ArticleJumpToCommentState.Inactive; var child = new Container( color: CColors.Background, child: new Column( children: new List <Widget> { this._buildNavigationBar(), new Expanded( child: new CustomScrollbar( new CenteredRefresher( controller: this._refreshController, enablePullDown: false, enablePullUp: this._article.hasMore, onRefresh: this._onRefresh, onNotification: this._onNotification, children: originItems, centerIndex: commentIndex ) ) ), this._buildArticleTabBar() } ) ); return(new Container( color: CColors.White, child: new CustomSafeArea( child: child ) )); }