~metalune/simplytranslate-devel

web: Add preferences page v1 APPLIED

fattalion: 1
 Add preferences page

 3 files changed, 152 insertions(+), 52 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~metalune/simplytranslate-devel/patches/27995/mbox | git am -3
Learn more about email & git

[PATCH web] Add preferences page Export this patch

---
 main.py              | 110 +++++++++++++++++++++++++++----------------
 templates/index.html |  32 ++++++++-----
 templates/prefs.html |  62 ++++++++++++++++++++++++
 3 files changed, 152 insertions(+), 52 deletions(-)
 create mode 100644 templates/prefs.html

diff --git a/main.py b/main.py
index 6db2b0a..1ac3cc2 100644
--- a/main.py
+++ b/main.py
@@ -58,6 +58,34 @@ app = Quart(__name__)

app.url_map.strict_slashes = False


def str_to_bool(s, **kwargs):
    if s is None and "default" in kwargs:
        return kwargs["default"]

    return s == "on" or s == "True"


def bool_to_str(b):
    return "True" if b else "False"


def dict_to_prefs(d, **kwargs):
    # For whatever reason, in HTML forms, the values of any unchecked
    # checkboxes are not sent at all, so we have this parameter that basically
    # disables the defaulting for any boolean settings.
    post_form = kwargs.get("post_form")

    return {
        # We don't need to consider `post_form` for `use_text_fields` since
        # it's off by default anyway, unlike `tts_enabled`.
        "use_text_fields": str_to_bool(d.get("use_text_fields")),
        "tts_enabled": str_to_bool(
            d.get("tts_enabled"), default=False if post_form else True
        ),
    }


# NOTE: Legacy Endpoint. Use "/api"
@app.route(
    "/translate/<string:from_language>/<string:to_language>/<string:input_text>/",
@@ -88,6 +116,37 @@ async def api_translate():
    return engine.translate(text, from_language=from_language, to_language=to_language)


@app.route("/prefs", methods=["POST", "GET"])
async def prefs():
    if request.method == "POST":
        prefs = dict_to_prefs(await request.form, post_form=True)
    elif request.method == "GET":
        prefs = dict_to_prefs(request.cookies)

    use_text_fields = prefs["use_text_fields"]
    tts_enabled = prefs["tts_enabled"]

    if request.method == "GET":
        return await render_template(
            "prefs.html",
            use_text_fields=use_text_fields,
            tts_enabled=tts_enabled,
        )
    elif request.method == "POST":
        response = await make_response(
            await render_template(
                "prefs.html",
                use_text_fields=use_text_fields,
                tts_enabled=tts_enabled,
            )
        )

        response.set_cookie("use_text_fields", bool_to_str(use_text_fields))
        response.set_cookie("tts_enabled", bool_to_str(tts_enabled))

        return response


@app.route("/api/get_languages/")
async def api_get_languages():
    engine_name = request.args.get("engine")
@@ -143,8 +202,6 @@ async def switchlanguages():
    if from_lang != "auto":
        from_lang, to_lang = to_lang, from_lang

    use_text_fields = request.args.get("typingiscool") == "True"

    """
    In case we ever want to also switch the translated text with the to-be-translated text, this is a good start.

@@ -157,7 +214,6 @@ async def switchlanguages():

    redirect_params = {
        "engine": engine_name,
        "typingiscool": use_text_fields,
        "sl": from_lang,
        "tl": to_lang,
        "text": text,
@@ -177,35 +233,6 @@ async def switchlanguages():
    return response


@app.route("/typingiscool/", methods=["POST"])
async def typingiscool():
    form = await request.form

    engine_name = request.args.get("engine")

    engine = get_engine(engine_name, engines, engines[0])

    text = form.get("input", "")
    from_lang = to_lang_code(form.get("from_language", "Autodetect"), engine)
    to_lang = to_lang_code(form.get("to_language", "English"), engine)

    use_text_fields = request.args.get("typingiscool") == "True"
    use_text_fields = not use_text_fields

    redirect_params = {
        "engine": engine_name,
        "typingiscool": use_text_fields,
        "sl": from_lang,
        "tl": to_lang,
        "text": text,
    }

    return redirect(
        f"/?{urlencode(redirect_params)}",
        code=302,
    )


@app.route("/", methods=["GET", "POST"])
async def index():
    engine_name = request.args.get("engine")
@@ -230,8 +257,8 @@ async def index():
            request.args.get("tl") or request.cookies.get("to_lang") or "en", engine
        )

        could_not_switch_languages = (
            request.args.get("could_not_switch_languages") == "True"
        could_not_switch_languages = str_to_bool(
            request.args.get("could_not_switch_languages")
        )
    elif request.method == "POST":
        form = await request.form
@@ -254,8 +281,6 @@ async def index():
            from_language=from_l_code,
        )

    use_text_fields = request.args.get("typingiscool") == "True"

    # TTS
    tts_from = None
    tts_to = None
@@ -269,6 +294,8 @@ async def index():
                params = {"engine": engine_name, "lang": to_l_code, "text": translation}
                tts_to = f"/api/tts/?{urlencode(params)}"

    prefs = dict_to_prefs(request.cookies)

    response = await make_response(
        await render_template(
            "index.html",
@@ -281,11 +308,11 @@ async def index():
            to_l=to_lang,
            to_l_code=to_l_code,
            engine=engine.name,
            #engines=[engine.name for engine in engines],
            # engines=[engine.name for engine in engines],
            engines=engines,
            
            supported_languages=engine.get_supported_languages(),
            use_text_fields=use_text_fields,
            use_text_fields=prefs["use_text_fields"],
            tts_enabled=prefs["tts_enabled"],
            could_not_switch_languages=could_not_switch_languages,
        )
    )
@@ -298,4 +325,7 @@ async def index():


if __name__ == "__main__":
    app.run(port=config.getint("network", "port", fallback=5000), host=str(config.get("network", "host", fallback="0.0.0.0"))) 
    app.run(
        port=config.getint("network", "port", fallback=5000),
        host=str(config.get("network", "host", fallback="0.0.0.0")),
    )
diff --git a/templates/index.html b/templates/index.html
index 155e19e..6766e6b 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -138,7 +138,7 @@
                                  {% if engine == _engine.name %}
                                    text-decoration: underline;
                                  {% endif %}
                            " href="/?engine={{ _engine.name }}&typingiscool={{ use_text_fields }}">
                            " href="/?engine={{ _engine.name }}">
                            {# These hyphens remove whitespace before/after the block.
                               They're here to remove the trailing space in the Google
                               engine link, which gets on yours truly's nerves.
@@ -160,20 +160,28 @@
            <!-- from and to language -->
            <div class="wrap">
                <div class="language">
                    <select name="from_language" id="from_language" aria-label="Source language">
                        {{ lang_option('Autodetect', from_l) }}
                        {{ supported_lang_options(from_l) }}
                    </select>
                    {% if use_text_fields %}
                        <input type="text" id="from_language" name="from_language" aria-label="Source language" value="{{ from_l }}" placeholder="from" />
                    {% else %}
                        <select name="from_language" id="from_language" aria-label="Source language">
                            {{ lang_option('Autodetect', from_l) }}
                            {{ supported_lang_options(from_l) }}
                        </select>
                    {% endif %}
                </div>

                <div class="switch_languages">
                    <button id="switchbutton" aria-label="Switch languages" formaction="/switchlanguages/?engine={{ engine }}&typingiscool={{ use_text_fields }}" type="submit"><-></button>
                    <button id="switchbutton" aria-label="Switch languages" formaction="/switchlanguages/?engine={{ engine }}" type="submit"><-></button>
                </div>

                <div class="language">
                    <select name="to_language" id="to_language" aria-label="Target language">
                        {{ supported_lang_options(to_l) }}
                    </select>
                    {% if use_text_fields %}
                        <input type="text" id="to_language" aria-label="Target language" name="to_language" value="{{ to_l }}" placeholder="from" />
                    {% else %}
                        <select name="to_language" id="to_language" aria-label="Target language">
                            {{ supported_lang_options(to_l) }}
                        </select>
                    {% endif %}
                </div>
            </div>

@@ -189,7 +197,7 @@
                <div class="item-wrapper">
                    <textarea autofocus class="item" id="input" name="input" dir="auto"  placeholder="Enter Text Here">{{ inp }}</textarea>
                    <!-- TTS for the input text -->
                    {%- if tts_from is not none -%}
                    {%- if tts_enabled and tts_from is not none -%}
                        <br>
                        <center>
                            <audio controls>
@@ -206,7 +214,7 @@
                        {%- if translation is not none -%}{{ translation }}{%- endif -%}
                    </textarea>
                    <!-- TTS for the output text -->
                    {%- if tts_to is not none -%}
                    {%- if tts_enabled and tts_to is not none -%}
                        <br>
                        <center>
                            <audio controls>
@@ -237,7 +245,7 @@

        <footer>
            <center>
                <a target="_new" href="https://simple-web.org/projects/simplytranslate.html">Project Page</a> | <a href="https://simple-web.org">Simple Web Project</a>
                <a href="/prefs">Preferences</a> | <a target="_new" href="https://simple-web.org/projects/simplytranslate.html">Project Page</a> | <a href="https://simple-web.org">Simple Web Project</a>
            </center>
        </footer>

diff --git a/templates/prefs.html b/templates/prefs.html
new file mode 100644
index 0000000..2e32772
--- /dev/null
+++ b/templates/prefs.html
@@ -0,0 +1,62 @@
<!DOCTYPE html>

<html>
    <head>
        <title>SimplyTranslate - Preferences</title>
        <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
        <meta name="description" content="Experience simple and private Google translations">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta charset="UTF-8">
        <style>
        body {
            max-width: 800px;
            margin: 10px auto;
        }

        @media screen and (prefers-color-scheme: dark) {
            body {
                background-color: #212529;
                color: #f8f9fa;
            }

            a:visited {
                color: #9759f6;
            }

            a {
                color: #599bf6;
            }
        }
        </style>
    </head>

    <body>
        <form action="/prefs" method="POST">
            <label for="use_text_fields">Use text fields for language selection:</label>
            <input
                type="checkbox"
                id="use_text_fields"
                name="use_text_fields"
                {% if use_text_fields %}checked{% endif %}>

            <br>

            <label for="tts_enabled">Enable text-to-speech:</label>

            <input
              type="checkbox"
              id="tts_enabled"
              name="tts_enabled"
              {% if tts_enabled %}checked{% endif %}>

            <br>
            <br>

            <button type="submit">Save preferences</button>
        </form>

        <br>

        <a href="/">Back To The Translator</a>
    </body>
</html>
-- 
2.34.1