Ejemplo n.º 1
0
        void FormatLabelTextToWrapLayout(WrapLayout wrapLayout, string text, Color color, FontAttributes fontAttributes = FontAttributes.None, LineBreakMode lineBreakMode = LineBreakMode.NoWrap, TapGestureRecognizer tap = null, string urlImg = null)
        {
            foreach (var line in text.Trim().Split(' '))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if (text == "img")
                {
                    Image img = new Image();
                    img.Source = urlImg;

                    if (tap != null)
                    {
                        img.GestureRecognizers.Add(tap);
                    }

                    wrapLayout.Orientation = StackOrientation.Vertical;
                    wrapLayout.Children.Add(img);
                }

                else
                {
                    Label lb = new Label()
                    {
                        FontAttributes = fontAttributes,
                        LineBreakMode  = lineBreakMode,
                        FontSize       = PlatformInvoke.IsWindows ? 15 : 16,
                        TextColor      = color,
                        Text           = line
                    };

                    if (tap != null)
                    {
                        lb.GestureRecognizers.Add(tap);
                    }

                    wrapLayout.Children.Add(lb);
                }
            }
        }
Ejemplo n.º 2
0
        void RenderText_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (IsRenderer || MessageHtml == null)
            {
                return;
            }
            IsRenderer = true;

            // Старт
            string SplitBbCode = "_SplitBbCode_";
            Color  textColor   = Color.FromHex("#464646");

            #region Начальный текст - (вырезаем весь код форматирования текста и заменяем часть кода на свой)
            string message_html = Regex.Replace(MessageHtml, "(<br />|<a [^>]+>([^<]+|<[^<]+>|<[a-z] +[^<]+</[a-z]>)</a>|<img [^>]+>|<[^>]+>|\\&lt;|\\&gt;|\\&nbsp;|\\&quot;)", rg =>
            {
                // Форматирование
                switch (rg.Groups[0].Value)
                {
                case "&quot;": return("\"");

                case "&lt;": return("<");

                case "&gt;": return(">");

                case "</p>":
                case "</li>":
                case "</code>":
                case "<hr>":
                case "<br>":
                case "<br />": return("<br />");

                case "<em>": return($"{SplitBbCode}em:");

                case "<strong>": return($"{SplitBbCode}strong:");

                case "</em>":
                case "</strong>": return($"{SplitBbCode}");
                }

                // Текста в <h*>*</h*>
                if (Regex.IsMatch(rg.Groups[0].Value, "</h[0-9]+>"))
                {
                    return("<br />");
                }

                // Изображение
                if (rg.Groups[0].Value.Contains("src="))
                {
                    return($"{SplitBbCode}img:{new Regex("src=\"([^\"]+)\"").Match(rg.Groups[0].Value).Groups[1].Value}{SplitBbCode}");
                }

                // Ссылка
                if (rg.Groups[0].Value.Contains("href="))
                {
                    var gLink = new Regex("href=\"([^\"]+)\"([^>]+)?>(.*)</a>").Match(rg.Groups[0].Value).Groups;

                    string title = gLink[3].Value;
                    title        = Regex.Replace(title, "<i +class=\"fa +fa-([^\"]+)\"></i>", "$1");
                    title        = Regex.Replace(title, "<img +src=\"/static/images/fugu/balloon(-|_)([a-z]+)\\..*", "$2");
                    return($"{SplitBbCode}link:{gLink[1].Value},{title}{SplitBbCode}");
                }

                // Удаляем
                return("");
            });
            #endregion

            // Дебаг
            //Debug.WriteLine(MessageHtml);

            #region Форматирования текста
            bool IsNewLineTwo = false;
            var  MassItem     = Regex.Split(message_html, "<br />");
            for (int i = 0; i < MassItem.Length; i++)
            {
                // Достаем строку
                string line = MassItem[i];

                // Максимум два \n
                if (string.IsNullOrWhiteSpace(line))
                {
                    if (IsNewLineTwo || i == MassItem.Length - 1 || string.IsNullOrWhiteSpace(MassItem[i + 1]))
                    {
                        continue;
                    }

                    IsNewLineTwo = true;
                    this.Children.Add(new Label());
                    continue;
                }
                else
                {
                    IsNewLineTwo = false;
                }

                // Костыльный StackLayout
                WrapLayout wrapLayout = new WrapLayout
                {
                    Orientation       = StackOrientation.Horizontal,
                    VerticalOptions   = LayoutOptions.Start,
                    HorizontalOptions = LayoutOptions.Start,
                    Padding           = 0,
                    Spacing           = 5
                };


                #region Формируем текст
                foreach (var splitLine in Regex.Split(line, SplitBbCode))
                {
                    if (string.IsNullOrWhiteSpace(splitLine))
                    {
                        continue;
                    }

                    // BB code
                    if (Regex.IsMatch(splitLine, "^(em|strong|link|img):"))
                    {
                        var grp = new Regex("^(em|strong|link|img):(.*)$").Match(splitLine).Groups;
                        if (string.IsNullOrWhiteSpace(grp[2].Value))
                        {
                            continue;
                        }

                        // Стили для текста
                        switch (grp[1].Value)
                        {
                        case "em":
                        case "strong":
                        {
                            FormatLabelTextToWrapLayout(wrapLayout, grp[2].Value, textColor, grp[1].Value == "em" ? FontAttributes.Italic : FontAttributes.Bold);
                            break;
                        }

                        case "img":
                        {
                            string url = grp[2].Value.Split(',')[0];
                            if (!url.Contains("/static/images/fugu/"))
                            {
                                goto case "link";
                            }

                            wrapLayout.Children.Add(new Image()
                                {
                                    Source               = url.Contains("freelancehunt.com") ? url : $"https://freelancehunt.com/{url}",
                                    HeightRequest        = 17,
                                    WidthRequest         = 17,
                                    MinimumHeightRequest = 17,
                                    MinimumWidthRequest  = 17,
                                    Margin               = new Thickness(0, 4, 0, 0),
                                    HorizontalOptions    = LayoutOptions.Start,
                                    VerticalOptions      = LayoutOptions.Start,
                                });
                            break;
                        }

                        case "link":
                        {
                            string url = grp[2].Value.Split(',')[0];
                            if (!Regex.IsMatch(url, "^https?://"))
                            {
                                url = "https://freelancehunt.com/" + Regex.Replace(url, "^/", "");
                            }

                            TapGestureRecognizer tap = new TapGestureRecognizer();
                            tap.Tapped += (s, et) =>
                            {
                                Device.OpenUri(new Uri(url));
                            };

                            FormatLabelTextToWrapLayout(wrapLayout, (grp[1].Value == "img" ? "img" : grp[2].Value.Split(',')[1]), Color.FromHex("#6ea6eb"), lineBreakMode: LineBreakMode.TailTruncation, tap: tap, urlImg: url);
                            break;
                        }
                        }
                    }

                    // Обычный текст
                    else
                    {
                        FormatLabelTextToWrapLayout(wrapLayout, splitLine, textColor);
                    }
                }

                this.Children.Add(wrapLayout);
                #endregion
            }
            #endregion
        }