public TranslatePopup(ITranslateService translateService, string text, string fromLanguage, string toLanguage, bool contentProtected)
        {
            InitializeComponent();

            _translateService = translateService;
            _fromLanguage     = fromLanguage == LANG_UND ? LANG_AUTO : fromLanguage;
            _toLanguage       = toLanguage;

            Title             = Strings.Resources.AutomaticTranslation;
            PrimaryButtonText = Strings.Resources.CloseTranslation;

            var tokenizedText = translateService.Tokenize(text, 1024);

            var fromName = LanguageName(fromLanguage, out bool rtl);
            var toName   = LanguageName(toLanguage, out _);

            if (string.IsNullOrEmpty(fromName))
            {
                SubtitleFrom.PlaceholderBrush = new SolidColorBrush(Colors.Transparent);
                SubtitleFrom.PlaceholderText  = toName;
            }
            else
            {
                SubtitleFrom.PlaceholderText = fromName;
            }

            Subtitle.Text = string.Format(" \u2192 {0}", toName);

            foreach (var token in tokenizedText)
            {
                var block = new LoadingTextBlock
                {
                    PlaceholderText          = token,
                    IsPlaceholderRightToLeft = rtl,
                    IsTextSelectionEnabled   = !contentProtected,
                    Margin = new Thickness(0, Presenter.Children.Count > 0 ? -8 : 0, 0, 0)
                };

                if (Presenter.Children.Count > 0)
                {
                    block.EffectiveViewportChanged += Block_EffectiveViewportChanged;
                }

                Presenter.Children.Add(block);
            }

            Opened += OnOpened;
        }
        private async Task TranslateTokenAsync(LoadingTextBlock block)
        {
            if (_loadingMore || block.PlaceholderText == null || block.Tag != null)
            {
                return;
            }

            _loadingMore = true;

            // Unsubscribe to disable load more
            block.EffectiveViewportChanged -= Block_EffectiveViewportChanged;
            block.Tag = new object();

            var ticks = Environment.TickCount;

            var response = await _translateService.TranslateAsync(block.PlaceholderText, _fromLanguage, _toLanguage);

            if (response is Translation translation)
            {
                var diff = Environment.TickCount - ticks;
                if (diff < 1000)
                {
                    await Task.Delay(1000 - diff);
                }

                block.Text        = translation.Text;
                SubtitleFrom.Text = LanguageName(translation.SourceLanguage, out _);
            }
            else if (response is Error error)
            {
                if (error.Code == 429)
                {
                    block.Text        = Strings.Resources.TranslationFailedAlert1;
                    SubtitleFrom.Text = LanguageName(_fromLanguage == LANG_AUTO ? _toLanguage : _fromLanguage, out _);
                }
                else
                {
                    block.Text        = Strings.Resources.TranslationFailedAlert2;
                    SubtitleFrom.Text = LanguageName(_fromLanguage == LANG_AUTO ? _toLanguage : _fromLanguage, out _);
                }
            }

            _loadingMore = false;
        }