mirror of
https://codeberg.org/aryak/mozhi
synced 2024-11-23 09:12:57 +05:30
webui finally
This commit is contained in:
parent
566eb69743
commit
8403dfe227
@ -76,3 +76,9 @@ These envvars turn off/on engines. By default all of them are enabled.
|
|||||||
|
|
||||||
## Etymology
|
## Etymology
|
||||||
Mozhi is the word in Tamil for language. Simple as that :P
|
Mozhi is the word in Tamil for language. Simple as that :P
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
- [Arya](https://aryak.me): creator
|
||||||
|
- [Midou36o](https://midou.dev): made the logo
|
||||||
|
- [Missuo](https://github.com/missuo): making gDeepLX that does the hard part of making DeepL work
|
||||||
|
- [SimplyTranslate](https://codeberg.org/simpleweb/simplytranslate): Inspiration and base code for the webui
|
||||||
|
5
TODO.md
5
TODO.md
@ -1,5 +1,8 @@
|
|||||||
# TODO
|
# TODO
|
||||||
- Create a web interface
|
- Support disabling engines with Web interface
|
||||||
|
- Make LibreTranslate work with web interface
|
||||||
|
- Write an about page for web
|
||||||
|
- Make detectlanguage swap the text as well
|
||||||
- Interactive/Step-by-step CLI
|
- Interactive/Step-by-step CLI
|
||||||
- Ability for user to choose engines they want to use
|
- Ability for user to choose engines they want to use
|
||||||
- Proper Error handling for requests.go
|
- Proper Error handling for requests.go
|
||||||
|
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.21.0
|
|||||||
replace github.com/OwO-Network/gdeeplx => github.com/gi-yt/gdeeplx v0.0.0-20230817133036-0eb71706cd51
|
replace github.com/OwO-Network/gdeeplx => github.com/gi-yt/gdeeplx v0.0.0-20230817133036-0eb71706cd51
|
||||||
|
|
||||||
require (
|
require (
|
||||||
codeberg.org/aryak/libmozhi v0.0.0-20230909133311-5b21e2215c4c
|
codeberg.org/aryak/libmozhi v0.0.0-20230909142818-70619214b1ea
|
||||||
github.com/gofiber/fiber/v2 v2.49.1
|
github.com/gofiber/fiber/v2 v2.49.1
|
||||||
github.com/gofiber/swagger v0.1.13
|
github.com/gofiber/swagger v0.1.13
|
||||||
github.com/gofiber/template v1.8.0
|
github.com/gofiber/template v1.8.0
|
||||||
|
2
go.sum
2
go.sum
@ -47,6 +47,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
codeberg.org/aryak/libmozhi v0.0.0-20230909133311-5b21e2215c4c h1:lnG0+NunYw4x6TUl00MQvucNTypqK6skms9MsKx0P2E=
|
codeberg.org/aryak/libmozhi v0.0.0-20230909133311-5b21e2215c4c h1:lnG0+NunYw4x6TUl00MQvucNTypqK6skms9MsKx0P2E=
|
||||||
codeberg.org/aryak/libmozhi v0.0.0-20230909133311-5b21e2215c4c/go.mod h1:DOxFxtSCKbs3sfKLxDwho9RFqkZy1opa67/c9v+/G+I=
|
codeberg.org/aryak/libmozhi v0.0.0-20230909133311-5b21e2215c4c/go.mod h1:DOxFxtSCKbs3sfKLxDwho9RFqkZy1opa67/c9v+/G+I=
|
||||||
|
codeberg.org/aryak/libmozhi v0.0.0-20230909142818-70619214b1ea h1:WqElyz20JDxXiQveo2TkNP2q0zyEK3i9VP5P6p7Dh7o=
|
||||||
|
codeberg.org/aryak/libmozhi v0.0.0-20230909142818-70619214b1ea/go.mod h1:DOxFxtSCKbs3sfKLxDwho9RFqkZy1opa67/c9v+/G+I=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
@ -1,26 +1,66 @@
|
|||||||
package pages
|
package pages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"codeberg.org/aryak/libmozhi"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleIndex(c *fiber.Ctx) error {
|
func HandleIndex(c *fiber.Ctx) error {
|
||||||
// Check if all required queries are present
|
engines := []string{"google", "deepl", "duckduckgo", "libretranslate", "mymemory", "reverso", "watson", "yandex"}
|
||||||
m := c.Queries()
|
var engine string
|
||||||
sl, _ := m["sl"]
|
var originalText string
|
||||||
tl, _ := m["tl"]
|
if c.Query("engine") == "" {
|
||||||
engine, _ := m["engine"]
|
engine = "google"
|
||||||
text, _ := m["text"]
|
}
|
||||||
if sl != "" && tl != "" && engine != "" && text != "" {
|
if c.Query("engine") != "" {
|
||||||
fmt.Println("Work")
|
for _, name := range engines {
|
||||||
|
if c.Query("engine") == name {
|
||||||
|
engine = c.Query("engine")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if engine == "" {
|
||||||
|
engine = "google"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceLanguages, err1 := libmozhi.LangList(engine, "sl")
|
||||||
|
targetLanguages, err2 := libmozhi.LangList(engine, "tl")
|
||||||
|
if err1 != nil || err2 != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err1.Error()+err2.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
originalText = c.Query("text")
|
||||||
|
to := c.Query("to")
|
||||||
|
from := c.Query("from")
|
||||||
|
var translation libmozhi.LangOut
|
||||||
|
var tlerr error
|
||||||
|
var ttsFrom string
|
||||||
|
var ttsTo string
|
||||||
|
if engine != "" && originalText != "" && from != "" && to != "" {
|
||||||
|
translation, tlerr = libmozhi.Translate(engine, to, from, originalText)
|
||||||
|
if tlerr != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, tlerr.Error())
|
||||||
|
}
|
||||||
|
if engine == "google" || engine == "reverso" {
|
||||||
|
if from == "auto" {
|
||||||
|
//ttsFrom = "/api/tts?lang="+translation.AutoDetect+"&engine="+engine+"&text="+originalText
|
||||||
|
ttsFrom = ""
|
||||||
|
} else {
|
||||||
|
ttsFrom = "/api/tts?lang="+from+"&engine="+engine+"&text="+originalText
|
||||||
|
}
|
||||||
|
ttsTo = "/api/tts?lang="+to+"&engine="+engine+"&text="+translation.OutputText
|
||||||
|
}
|
||||||
|
}
|
||||||
return c.Render("index", fiber.Map{
|
return c.Render("index", fiber.Map{
|
||||||
"host": c.Hostname(),
|
"Engine": engine,
|
||||||
"fiberversion": fiber.Version,
|
"enginesNames": engines,
|
||||||
"goversion": runtime.Version(),
|
"SourceLanguages": sourceLanguages,
|
||||||
|
"TargetLanguages": targetLanguages,
|
||||||
|
"OriginalText": originalText,
|
||||||
|
"Translation": translation,
|
||||||
|
"From": from,
|
||||||
|
"To": to,
|
||||||
|
"TtsFrom": ttsFrom,
|
||||||
|
"TtsTo": ttsTo,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,380 +0,0 @@
|
|||||||
/* god bless you */
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--text: #fff;
|
|
||||||
--background: #252525;
|
|
||||||
--secondary-background: #353535;
|
|
||||||
--background-darker: #151515;
|
|
||||||
--accent: #00b7c3;
|
|
||||||
--yellow: #8b8000;
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui,
|
|
||||||
helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
|
|
||||||
sans-serif;
|
|
||||||
color: var(--text);
|
|
||||||
background-color: var(--background-darker);
|
|
||||||
transition: ease-in-out 0.25s;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 8px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 8px;
|
|
||||||
background: var(--background);
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
margin: 0 24vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.margin-ow {
|
|
||||||
margin: 0 12vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
overflow: scroll;
|
|
||||||
background: var(--secondary-background);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrap {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.navbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-direction: row;
|
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
background-color: var(--background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.index-gh {
|
|
||||||
background: var(--background);
|
|
||||||
color: var(--text);
|
|
||||||
padding: 4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
transition: ease-in-out 0.25s;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-slogan:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
text-underline-offset: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand:hover {
|
|
||||||
color: var(--text);
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
background-color: var(--background);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui,
|
|
||||||
helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
|
|
||||||
sans-serif;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--text);
|
|
||||||
text-decoration: underline;
|
|
||||||
text-underline-offset: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-notice {
|
|
||||||
background-color: var(--yellow);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui,
|
|
||||||
helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
|
|
||||||
sans-serif;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-notice > a {
|
|
||||||
text-decoration: underline;
|
|
||||||
text-underline-offset: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-notice > a:hover {
|
|
||||||
color: var(--text);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* URI: /explore */
|
|
||||||
|
|
||||||
.explore-card,
|
|
||||||
.user-repo-card {
|
|
||||||
background-color: var(--background);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px 0 8px 0;
|
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: wrap;
|
|
||||||
text-decoration: none;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
transition: ease-in-out 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.explore-card:hover,
|
|
||||||
.user-repo-card:hover {
|
|
||||||
background-color: var(--secondary-background);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* URI: /:user */
|
|
||||||
|
|
||||||
.user-profile {
|
|
||||||
background-color: var(--background);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile h1 {
|
|
||||||
color: var(--accent);
|
|
||||||
margin: 4px;
|
|
||||||
word-wrap: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile h2 {
|
|
||||||
margin: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile p {
|
|
||||||
margin: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile img {
|
|
||||||
border: 4px solid var(--accent);
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-bio,
|
|
||||||
.user-readme {
|
|
||||||
background-color: var(--background);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-bio-text,
|
|
||||||
.user-readme-text {
|
|
||||||
background-color: var(--background-darker);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-readme-text {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-links {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-repo-card {
|
|
||||||
background-color: var(--background-darker);
|
|
||||||
padding: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px 0 8px 0;
|
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: wrap;
|
|
||||||
text-decoration: none;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
transition: ease-in-out 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-repo-card > p {
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-repo-card:hover {
|
|
||||||
background-color: var(--secondary-background);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.lang-bar:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lang-bar {
|
|
||||||
width: 100%;
|
|
||||||
display: inherit;
|
|
||||||
height: 10px;
|
|
||||||
border-radius:4px;
|
|
||||||
overflow: hidden; /* To force the corners to be round. */
|
|
||||||
user-select: none; /* Prevent the selection */
|
|
||||||
-webkit-user-select: none; /* Safari specific fix. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* URI: /:user/:repo */
|
|
||||||
.button {
|
|
||||||
background-color: var(--background);
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px;
|
|
||||||
color: var(--text);
|
|
||||||
text-decoration: none;
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
background-color: var(--secondary-background);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-parent {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-list {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-u-list {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* URI: /file/:user/:repo/:file */
|
|
||||||
.user-readme pre {
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
/*white-space: pre-wrap;*/
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background-color: var(--secondary-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overwrite */
|
|
||||||
|
|
||||||
.no-margin {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-padding {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.float-right {
|
|
||||||
float: right;
|
|
||||||
display: grid;
|
|
||||||
flex: none;
|
|
||||||
align-self: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (prefers-color-scheme: light) {
|
|
||||||
:root {
|
|
||||||
--text: #000;
|
|
||||||
--background: #ececec;
|
|
||||||
--secondary-background: #f5f5f5;
|
|
||||||
--background-darker: #dddddd;
|
|
||||||
--accent: #005ec3;
|
|
||||||
--yellow: #f5f5a5;
|
|
||||||
color-scheme: light;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #005ec3;
|
|
||||||
}
|
|
||||||
.explore-card {
|
|
||||||
background-color: var(--background);
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 900px) {
|
|
||||||
main {
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.float-right {
|
|
||||||
float: none;
|
|
||||||
display: inline-grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-slogan {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbarImg {
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.explore-card {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-links {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cl {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
171
public/css/style.css
Normal file
171
public/css/style.css
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*General theming*/
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin: 20px auto;
|
||||||
|
max-width: 1100px;
|
||||||
|
line-height: 1.5em;
|
||||||
|
font-size: 1.1em;
|
||||||
|
background-color: #222;
|
||||||
|
color: #f8f9fa;
|
||||||
|
padding: 0 10px;
|
||||||
|
hyphens: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
border-bottom: 1px solid #b2b2b2;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
width: 95%;
|
||||||
|
border-top: 1px solid #b2b2b2;
|
||||||
|
}
|
||||||
|
footer p {
|
||||||
|
margin: 0.2em 0 0.2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3c67ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
nav li {
|
||||||
|
display: inline-block no;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
.navlogo {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Theming for buttons and text areas*/
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 4px;
|
||||||
|
border: 2px solid #888888;
|
||||||
|
background-color: #222;
|
||||||
|
border-color: #9d9d9d;
|
||||||
|
color: #f8f9fa;
|
||||||
|
}
|
||||||
|
textarea:focus {
|
||||||
|
border-color: #e5ebff;
|
||||||
|
outline: 1px solid #e5ebff;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
display: flex;
|
||||||
|
padding: 4px 8px;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1 0 0;
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: none;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 2px solid #3c67ff;
|
||||||
|
/* Accent shadow */
|
||||||
|
box-shadow: 2px 2px 0px 0px rgba(60, 103, 255, 0.25);
|
||||||
|
color: #b2b2b2;
|
||||||
|
background-color: #2f2f2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: flex;
|
||||||
|
padding: 4px 8px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #3c67ff;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
box-shadow: 5px 5px 0px 0px rgba(60, 103, 255, 0.25);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spacing stuff */
|
||||||
|
.wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.wrap.languages {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language {
|
||||||
|
margin: 0px 10px;
|
||||||
|
}
|
||||||
|
.item {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
.item-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
width: 450px;
|
||||||
|
margin: 5px 10px;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CSS for the custom engine selector */
|
||||||
|
.custom-select {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-option {
|
||||||
|
display: block;
|
||||||
|
padding: 7px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #222;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options li {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options li:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-select:hover .options {
|
||||||
|
display: block;
|
||||||
|
}
|
@ -85,10 +85,18 @@ func Serve(port string) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/", pages.HandleIndex)
|
app.Get("/", pages.HandleIndex)
|
||||||
|
app.Get("/switchlanguages", func(c *fiber.Ctx) error {
|
||||||
|
engine := c.Query("engine")
|
||||||
|
from := c.Query("from")
|
||||||
|
to := c.Query("to")
|
||||||
|
text := c.Query("text")
|
||||||
|
return c.Redirect("/?engine="+engine+"&from="+to+"&to="+from+"&text="+text+"&redirected=true", 301)
|
||||||
|
})
|
||||||
app.Static("/css", "./public/css", staticConfig)
|
app.Static("/css", "./public/css", staticConfig)
|
||||||
app.Static("/robots.txt", "./public/robots.txt", staticConfig)
|
app.Static("/robots.txt", "./public/robots.txt", staticConfig)
|
||||||
app.Static("/favicon.ico", "./public/assets/favicon.ico", staticConfig)
|
app.Static("/favicon.ico", "./public/assets/favicon.ico", staticConfig)
|
||||||
app.Static("/mozhi.svg", "./public/assets/mozhi.svg", staticConfig)
|
app.Static("/mozhi.svg", "./public/assets/mozhi.svg", staticConfig)
|
||||||
|
app.Static("/mozhi.png", "./public/assets/mozhi.png", staticConfig)
|
||||||
// app.Get("/about", pages.HandleAbout)
|
// app.Get("/about", pages.HandleAbout)
|
||||||
|
|
||||||
api := app.Group("/api")
|
api := app.Group("/api")
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
{{ template "header" .}}
|
|
||||||
<main>
|
|
||||||
<div class="center">
|
|
||||||
<h1 style="color: red">Error</h1>
|
|
||||||
<h2>
|
|
||||||
Someone pushed to production. Just kidding, that's probably not what
|
|
||||||
happened. Here's the error:
|
|
||||||
</h2>
|
|
||||||
<pre class="error">{{.error}}</pre>
|
|
||||||
<h3>
|
|
||||||
Think this is a bug?
|
|
||||||
<a href="https://codeberg.org/aryak/mozhi/issues" target="_blank"
|
|
||||||
>Create an issue on Codeberg.</a
|
|
||||||
>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{{ template "footer" .}}
|
|
@ -1,5 +1,14 @@
|
|||||||
<footer class="center">
|
<br />
|
||||||
<a href="https://codeberg.org/aryak/mozhi">Codeberg</a> | <a href="/instance">About Instance</a>
|
<footer style="text-align: center">
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
Copyright 2023 <a href="https://aryak.me">Arya Kiran</a> and other
|
||||||
|
contributors
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
View Source Code on
|
||||||
|
<a href="https://codeberg.org/aryak/mozhi">Codeberg</a>
|
||||||
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -6,8 +6,23 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<title>Mozhi</title>
|
<title>Mozhi</title>
|
||||||
{{end}}
|
{{end}}
|
||||||
<link rel="stylesheet" href="/css/global.css">
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
name="description"
|
||||||
|
content="Mozhi is an alternative-frontend for many translation engines."
|
||||||
|
/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="referrer" content="no-referrer" />
|
||||||
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<header>
|
||||||
|
<a href="/"><img src="/mozhi.png" alt="Mozhi Logo" class="navlogo" /></a>
|
||||||
|
<nav>
|
||||||
|
<a href="/about">About</a>
|
||||||
|
<a href="/api/swagger">API</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<br />
|
||||||
|
113
views/index.html
113
views/index.html
@ -1,28 +1,95 @@
|
|||||||
{{template "header" .}}
|
{{template "header" .}}
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h2>Mozhi</h2>
|
<!-- Need to do this custom selector thingy since <select> cant submit on click -->
|
||||||
<h3>Translate</h3>
|
<div class="custom-select">
|
||||||
|
Translate with: <a href="#" class="selected-option">{{.Engine}}</a>
|
||||||
<form action="/" method="get">
|
<ul class="options">
|
||||||
<label for="textin">Text To Translate:</label>
|
{{range .enginesNames}}
|
||||||
<textarea id="textin" name="textin" rows="4" cols="50"></textarea>
|
<a href="/?engine={{.}}"><li>{{.}}</li></a>
|
||||||
<input type="checkbox" name="vehicle1" value="Bike">
|
|
||||||
<label for="vehicle1"> I have a bike</label><br>
|
|
||||||
<input type="checkbox" name="vehicle2" value="Car">
|
|
||||||
<label for="vehicle2"> I have a car</label><br>
|
|
||||||
<input type="checkbox" name="vehicle3" value="Boat" checked>
|
|
||||||
<label for="vehicle3"> I have a boat</label><br><br>
|
|
||||||
<input type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
<h3>Info</h3>
|
|
||||||
{{ if eq .version "unknown, please build with Go 1.13+ or use Git"}} Mozhi
|
|
||||||
version: <code>unknown</code> {{ else }} Mozhi version:
|
|
||||||
<a href="https://codeberg.org/aryak/mozhi/commit/{{ .version}}"
|
|
||||||
><code>{{ .version}}</code></a
|
|
||||||
>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
<br />
|
</ul>
|
||||||
Fiber version: {{ .fiberversion}}, running on {{ .goversion}}
|
</div>
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
<form action="/" method="GET" id="translation-form">
|
||||||
|
<!-- This hidden input is so that the engine gets sent in the GET request even though its not declared here -->
|
||||||
|
<input name="engine" value="{{.Engine}}" type="hidden" />
|
||||||
|
|
||||||
|
<div class="wrap languages">
|
||||||
|
<div class="language">
|
||||||
|
<select name="from" aria-label="Source language">
|
||||||
|
{{range $key, $value := .SourceLanguages}}
|
||||||
|
<option value="{{ .Id }}" {{if eq $.From .Id}}selected{{end}}>
|
||||||
|
{{ .Name }}
|
||||||
|
</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="switch_languages">
|
||||||
|
<button
|
||||||
|
id="switchbutton"
|
||||||
|
aria-label="Switch languages"
|
||||||
|
formaction="/switchlanguages?engine={{ .Engine }}"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<->
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="language">
|
||||||
|
<select name="to" aria-label="Target language">
|
||||||
|
{{range $key, $value := .TargetLanguages}}
|
||||||
|
<option value="{{ .Id }}" {{if eq $.To .Id}}selected{{end}}>
|
||||||
|
{{ .Name }}
|
||||||
|
</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="item-wrapper">
|
||||||
|
<textarea
|
||||||
|
autofocus
|
||||||
|
class="item"
|
||||||
|
id="input"
|
||||||
|
name="text"
|
||||||
|
dir="auto"
|
||||||
|
placeholder="Enter Text Here"
|
||||||
|
>
|
||||||
|
{{ .OriginalText }}</textarea
|
||||||
|
>
|
||||||
|
{{if .TtsFrom}}
|
||||||
|
<audio controls>
|
||||||
|
<source type="audio/mpeg" src="{{ .TtsFrom }}" />
|
||||||
|
</audio>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item-wrapper">
|
||||||
|
<textarea
|
||||||
|
id="output"
|
||||||
|
class="translation item"
|
||||||
|
dir="auto"
|
||||||
|
placeholder="Translation"
|
||||||
|
readonly
|
||||||
|
>
|
||||||
|
{{.Translation.OutputText}}</textarea
|
||||||
|
>
|
||||||
|
{{if .Translation.AutoDetect}}
|
||||||
|
<p>
|
||||||
|
Detected Language: {{.Translation.AutoDetect}}{{end}} {{if .TtsTo}}
|
||||||
|
<audio controls>
|
||||||
|
<source type="audio/mpeg" src="{{ .TtsTo }}" />
|
||||||
|
</audio>
|
||||||
|
{{end}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center">
|
||||||
|
<button type="submit">Translate with {{ .Engine }}!</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</main>
|
</main>
|
||||||
{{ template "footer" .}}
|
{{ template "footer" .}}
|
||||||
|
Loading…
Reference in New Issue
Block a user