Exemplo n.º 1
0
        static void HandleNimigemActivate(Uri uri)
        {
            var preformattedLines  = new List <GeminiLine>();
            var exitedPreformatted = false;
            var enteredPreformat   = false;
            var foundNimigemEdit   = false;

            var currentLine = _lineView.SelectedItem;

            var activatedLine = (GeminiLine)_lineView.Source.ToList()[currentLine];

            //check if it is hinted as a null payload link
            if (activatedLine.Line.StartsWith('\u2205'.ToString()))
            {
                //send null payload
                try
                {
                    SubmitNimigem(uri, Encoding.UTF8.GetBytes(""), "text/plain");
                }
                catch (Exception e)
                {
                    Dialogs.MsgBoxOK("Nimigem error", "Nimigem error: " + e.Message);
                }
                return;
            }

            //search back in the page for the linked text area
            //gather the previous nimigem lines and let the user edit the text
            while (currentLine >= 0)
            {
                var gemLine = (GeminiLine)_lineView.Source.ToList()[currentLine];

                if (gemLine.LineType == "```+")
                {
                    enteredPreformat = true;
                    foundNimigemEdit = true;        //strictly speaking this will ignore all nimigem areas that are empty...
                }

                if (enteredPreformat & gemLine.LineType != "```+")
                {
                    exitedPreformatted = true;
                }

                if (!exitedPreformatted && enteredPreformat && gemLine.LineType == "```+")
                {
                    //we found a line in the first preceeding preformatted area
                    preformattedLines.Add(gemLine);
                }

                currentLine--;
            }


            var sb = new StringBuilder();

            preformattedLines.Reverse();

            for (int n = 0; n < preformattedLines.Count; n++)
            {
                var editLine = preformattedLines[n];

                //nimigem spec requires any required preformatted markers inside
                //editable preformatted areas to be escaped with zero width space
                if (editLine.Line.StartsWith('\u200b'.ToString() + "```"))
                {
                    sb.Append(editLine.Line.Substring(1));      //trim leading zero width space used to escape preformatted markers
                }
                else
                {
                    sb.Append(editLine.Line);
                }

                //append newline to all except the last one
                if (n < preformattedLines.Count - 1)
                {
                    sb.Append("\n");
                }
            }

            if (foundNimigemEdit)
            {
                var userEdit = Dialogs.MultilineInputBox("Nimigem edit", "Edit the text to be sent to: " + uri.AbsoluteUri, sb.ToString());

                if (userEdit.ButtonPressed == TextDialogResponse.Buttons.Ok)
                {
                    try
                    {
                        //send as plain text, utf8
                        SubmitNimigem(uri, Encoding.UTF8.GetBytes(userEdit.Text), "text/plain");
                    }
                    catch (Exception e)
                    {
                        Dialogs.MsgBoxOK("Nimigem error", "Nimigem error: \n" + e.Message);
                    }
                }
            }
            else
            {
                //No associated preceding Nimigem editable preformatted area was found.
                //so send a file

                //show a dialog to choose a file
                var openDialog = new Terminal.Gui.OpenDialog("Nimigem upload", "Choose a file to send to the Nimigem server");
                Application.Run(openDialog);

                if (openDialog.FilePaths.Count > 0)
                {
                    var selectedPath = openDialog.FilePaths[0];
                    var bytes        = File.ReadAllBytes(selectedPath);
                    var extension    = Path.GetExtension(selectedPath);

                    // since text/gemini is not widely known but might be more common for users of a gemini client
                    // we test for it, otherwise we use the MimeTypes library to infer it
                    var mediaType = (extension == ".gmi" || extension == ".gemini") ? "text/gemini" : MimeTypes.GetMimeType(selectedPath);

                    try
                    {
                        SubmitNimigem(uri, bytes, mediaType);                       //send to the server
                    }
                    catch (Exception e)
                    {
                        Dialogs.MsgBoxOK("Nimigem error", "Nimigem error: \n" + e.Message);
                    }
                }
            }
        }
Exemplo n.º 2
0
        static void LoadGeminiLink(Uri uri)
        {
            string         result;
            bool           retrieved = false;
            GeminiResponse resp;

            resp = new GeminiResponse();

            try
            {
                resp      = (GeminiResponse)Gemini.Fetch(uri);
                retrieved = true;
            }
            catch (Exception e)
            {
                //the native gui.cs Messagebox does not resize to show enough content
                //so we use our own that is better
                Dialogs.MsgBoxOK("Gemini error", uri.AbsoluteUri + "\n\n" + e.Message);
            }

            if (retrieved)
            {
                if (resp.codeMajor == '2')
                {
                    //examine the first component of the media type up to any semi colon
                    switch (resp.mime.Split(';')[0].Trim())
                    {
                    case "text/gemini":
                    case "text/plain":
                    case "text/html":
                    {
                        string body = Encoding.UTF8.GetString(resp.bytes.ToArray());

                        result = (body);

                        if (!resp.mime.StartsWith("text/gemini"))
                        {
                            //display as preformatted text
                            result = "```\n" + result + "\n```\n";
                        }

                        break;
                    }

                    default:     // report the mime type only for now
                        result = ("Some " + resp.mime + " content was received, but cannot currently be displayed.");
                        break;
                    }

                    //render the content and add to history
                    SetAsCurrent(resp.uri);             //remember the final URI, since it may have been redirected.

                    if (_history.Count > 0)
                    {
                        _history.Peek().top      = _lineView.TopItem;
                        _history.Peek().selected = _lineView.SelectedItem;        //remember the line offset of the current page
                    }
                    _history.Push(new CachedPage(resp.uri, result, 0, 0));

                    RenderGemini(resp.uri.AbsoluteUri, result, _lineView);
                }
                else if (resp.codeMajor == '1')
                {
                    //input requested from server
                    var userResponse = Dialogs.SingleLineInputBox("Input request from: " + uri.Authority, resp.meta, "");

                    if ((userResponse.ButtonPressed == TextDialogResponse.Buttons.Ok) && (userResponse.Text != ""))
                    {
                        var ub = new UriBuilder(uri);
                        ub.Query = userResponse.Text;

                        LoadGeminiLink(ub.Uri);
                    }
                }
                else if ((resp.codeMajor == '5') && (resp.codeMinor == '1'))
                {
                    //not found
                    Dialogs.MsgBoxOK("Not found", "The resource was not found on the server: \n\n" + resp.uri.AbsoluteUri);
                }
                else
                {
                    Dialogs.MsgBoxOK("Gemini server response", uri.AbsoluteUri + "\n\n" + "Status: " + resp.codeMajor + resp.codeMinor + ": " + resp.meta);
                }
            }
        }