diff options
| -rw-r--r-- | form.html | 213 | ||||
| -rw-r--r-- | main.go | 19 | ||||
| -rw-r--r-- | post.html | 31 |
3 files changed, 220 insertions, 43 deletions
diff --git a/form.html b/form.html new file mode 100644 index 0000000..a5de342 --- /dev/null +++ b/form.html @@ -0,0 +1,213 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Gloginki</title> + + <style> + :root { + --bg: #f6f8fa; + --card-bg: #ffffff; + --border: #d0d7de; + --text: #24292f; + --muted: #57606a; + --primary: #2da44e; + --primary-hover: #2c974b; + --danger: #cf222e; + --radius: 6px; + } + + * { + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", + Helvetica, Arial, sans-serif; + } + + body { + margin: 0; + padding: 2rem; + background: var(--bg); + color: var(--text); + } + + h1 { + margin-bottom: 1rem; + font-size: 1.6rem; + } + + .container { + max-width: 900px; + margin: 0 auto; + } + + #error { + color: var(--danger); + margin-bottom: 1rem; + font-weight: 500; + } + + form { + background: var(--card-bg); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.5rem; + margin-bottom: 2rem; + } + + fieldset { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1rem; + margin-bottom: 1.2rem; + } + + legend { + padding: 0 0.5rem; + color: var(--muted); + font-size: 0.9rem; + } + + textarea { + width: 100%; + min-height: 250px; + resize: vertical; + padding: 0.75rem; + border-radius: var(--radius); + border: 1px solid var(--border); + font-size: 0.95rem; + } + + textarea:focus, + input:focus { + outline: none; + border-color: #0969da; + } + + input[type="file"], + input[type="text"] { + margin-top: 0.5rem; + } + + .submit-row { + display: flex; + gap: 1rem; + align-items: center; + flex-wrap: wrap; + } + + input[type="submit"] { + background: var(--primary); + color: white; + border: none; + padding: 0.6rem 1.2rem; + border-radius: var(--radius); + font-weight: 600; + cursor: pointer; + } + + input[type="submit"]:hover { + background: var(--primary-hover); + } + + /* Preview card */ + #preview-container { + background: var(--card-bg); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1rem; + } + + #preview-container h2 { + margin-top: 0; + font-size: 1rem; + color: var(--muted); + } + + #preview { + max-width: 100%; + border-radius: var(--radius); + display: none; + } + + .hint { + font-size: 0.85rem; + color: var(--muted); + margin-top: 0.5rem; + } + </style> +</head> + +<body> + <div class="container"> + <h1>Bin-ки и глогинки.</h1> + + <div id="error"></div> + + <form enctype="multipart/form-data" action="/post" method="post"> + <fieldset> + <legend>Text Posting</legend> + <textarea name="text" placeholder="Write something..."></textarea> + </fieldset> + + <fieldset> + <legend>File Upload</legend> + <input type="file" name="file" /> + <div class="hint">You can also paste an image directly</div> + </fieldset> + + <fieldset> + <legend>Submit</legend> + <div class="submit-row"> + <label> + Mime-type: + <input type="text" name="mimetype" value="auto" /> + </label> + <input type="submit" value="Post" /> + </div> + </fieldset> + </form> + + <div id="preview-container"> + <h2>Image Preview</h2> + <img id="preview" /> + <div class="hint" id="preview-hint">Paste an image to preview it</div> + </div> + </div> + + <script> + const pasteArea = document.body; + const preview = document.getElementById("preview"); + const previewHint = document.getElementById("preview-hint"); + const form = document.querySelector("form"); + + let pastedFile = null; + + pasteArea.addEventListener("paste", (event) => { + const items = event.clipboardData.items; + + for (const item of items) { + if (item.type.startsWith("image/")) { + pastedFile = item.getAsFile(); + + preview.src = URL.createObjectURL(pastedFile); + preview.style.display = "block"; + previewHint.style.display = "none"; + + event.preventDefault(); + break; + } + } + }); + + form.addEventListener("submit", () => { + if (pastedFile) { + const fileInput = form.querySelector('input[type="file"]'); + const dt = new DataTransfer(); + dt.items.add(pastedFile); + fileInput.files = dt.files; + } + }); + </script> +</body> +</html> @@ -33,7 +33,7 @@ type Metadata struct { ContentType string `json:"contentType"` } -//go:embed post.html +//go:embed form.html var static embed.FS func detectMimetype(input io.Reader) (mimeType string, fileext string, recycled io.Reader, err error) { @@ -158,13 +158,6 @@ func (s *Server) formPost(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusFound) } -func (s *Server) formGet(w http.ResponseWriter, r *http.Request) { - f, _ := static.Open("post.html") - if _, err := io.Copy(w, f); err != nil { - w.WriteHeader(http.StatusInternalServerError) - } -} - func (s *Server) servePosting(w http.ResponseWriter, r *http.Request, name string) { filename := filepath.Join(s.data, name) m, err := readMetadata(filename + MetadataExt) @@ -240,8 +233,11 @@ func (s *Server) indexPost(w http.ResponseWriter, r *http.Request) { func (s *Server) indexGet(w http.ResponseWriter, r *http.Request) { path := r.URL.Path if path == "/" { - w.Header().Add("content-type", "text/plain; charset=UTF-8") - w.Write([]byte("Bin-ки и глогинки.")) + w.Header().Add("content-type", "text/html; charset=UTF-8") + f, _ := static.Open("form.html") + if _, err := io.Copy(w, f); err != nil { + w.WriteHeader(http.StatusInternalServerError) + } } else { s.servePosting(w, r, filepath.Base(path)) } @@ -249,11 +245,10 @@ func (s *Server) indexGet(w http.ResponseWriter, r *http.Request) { func (s *Server) Post(w http.ResponseWriter, r *http.Request) { switch r.Method { - case http.MethodGet: - s.formGet(w, r) case http.MethodPost: s.formPost(w, r) default: + w.WriteHeader(http.StatusBadRequest) } } diff --git a/post.html b/post.html deleted file mode 100644 index 3ed8f1b..0000000 --- a/post.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <meta http-equiv="X-UA-Compatible" content="ie=edge" /> - <title>Gloginki</title> - </head> - <body> - <form - enctype="multipart/form-data" - action="/post" - method="post" - > - <fieldset> - <legend>Text Posting</legend> - <textarea name="text" style="width:100%;min-height:300px;"></textarea> - </fieldset> - <fieldset> - <legend>File Upload</legend> - <input type="file" name="file" /> - </fieldset> - <fieldset> - <legend>Submit</legend> - <label for="mimetype">Mime-type:</label> - <input type="text" name="mimetype" value="auto" /> - <input type="submit" value="Post" /> - </fieldset> - </form> - </body> -</html>
\ No newline at end of file |
