initial commit
This commit is contained in:
commit
c21f569144
37 changed files with 3956 additions and 0 deletions
1228
views/static/css/github-markdown.css
Normal file
1228
views/static/css/github-markdown.css
Normal file
File diff suppressed because it is too large
Load diff
78
views/static/css/input.css
Normal file
78
views/static/css/input.css
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
@import "tailwindcss";
|
||||
|
||||
/* não deve ser o jeito certo de fazer isso. */
|
||||
|
||||
.primary_button {
|
||||
@apply rounded p-2 bg-indigo-500;
|
||||
}
|
||||
|
||||
.my-input {
|
||||
@apply w-full bg-transparent placeholder:text-slate-400 text-slate-700 text-sm border border-slate-200 rounded-md px-3 py-2 transition duration-300 focus:outline-none focus:border-slate-400 hover:border-slate-300 shadow-sm focus:shadow;
|
||||
}
|
||||
|
||||
.my-label {
|
||||
@apply block mb-1 text-sm text-slate-600;
|
||||
}
|
||||
|
||||
.however {
|
||||
@apply flex items-center mt-2 text-xs text-slate-400;
|
||||
}
|
||||
|
||||
.my-my-input {
|
||||
@apply w-full min-w-[200px] mb-5;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply w-full rounded-md bg-slate-800 py-2 px-4 my-4 border border-transparent text-center text-sm text-white transition-all shadow-md hover:shadow-lg focus:bg-slate-700 focus:shadow-none active:bg-slate-700 hover:bg-slate-700 active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-5xl font-bold mb-5
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-4xl font-bold mb-5
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@keyframes bounce {
|
||||
0% {
|
||||
transform: translateX(-7px);
|
||||
timing-function: ease-in;
|
||||
}
|
||||
37% {
|
||||
transform: translateX(7px);
|
||||
timing-function: ease-out;
|
||||
}
|
||||
55% {
|
||||
transform: translateX(-7px);
|
||||
timing-function: ease-in;
|
||||
}
|
||||
73% {
|
||||
transform: translateX(5px);
|
||||
timing-function: ease-out;
|
||||
}
|
||||
82% {
|
||||
transform: translateX(-5px);
|
||||
timing-function: ease-in;
|
||||
}
|
||||
91% {
|
||||
transform: translateX(2px);
|
||||
timing-function: ease-out;
|
||||
}
|
||||
96% {
|
||||
transform: translateX(-2px);
|
||||
timing-function: ease-in;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0px);
|
||||
timing-function: ease-in;
|
||||
}
|
||||
}
|
||||
|
||||
.bounce {
|
||||
animation-name: bounce;
|
||||
animation-duration: .5s;
|
||||
}
|
||||
74
views/static/default/README.md
Normal file
74
views/static/default/README.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
# **This box URL belongs to no one.**
|
||||
|
||||
**Drop a file** with the `Edit code` field of your choice **to claim this URL as yours**.
|
||||
|
||||
So as long as you **keep your edit code**, you will be able to make permissive moditifications to this box,
|
||||
including visualizing files, moderation and exclusion of files.
|
||||
|
||||
**To make modifications to this readme section, drop a file called `README.md`** that will override the
|
||||
currently set header. This is how you're supposed to make edits to this section.
|
||||
|
||||
New boxes have been set to have a **maximum lifetime of two years,** after the lifetime period is over,
|
||||
the box files are going to be deleted and the URL is going to be reclaimed. You'll no longer own this URL.
|
||||
|
||||
Once you've claimed this box, you'll be able to **drop a `config.json5`** with valid [`json5`](https://json5.org/) options
|
||||
**to replace the default box configuration.** [The default configuration file can be found
|
||||
here](/box-configurations#) along with all customizeble options.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Can I set a maximum upload size?
|
||||
|
||||
Works is in progress. You won't be able to set it above the maximum size set be this instance administrator
|
||||
|
||||
### Is there a views counter?
|
||||
|
||||
Works is in progress. There will be one.
|
||||
|
||||
### Can I block others from viewing the box contents?
|
||||
|
||||
Works is in progress. You will be able to.
|
||||
|
||||
### What filetypes are allowed? Can I black/white list filetypes?
|
||||
|
||||
Per the default configuration, all filetypes are allowed. but works are in progress. You will be able to
|
||||
white or blacklist filetypes.
|
||||
|
||||
### How can I see the IP addresses of the file uploaders
|
||||
|
||||
You cannot and there is no configuration you or the instance administrator can set that will allow you
|
||||
to see address of the uploaders because the servers don't collect them in the first place.
|
||||
Let it be known that the instance administrator can still set the server to run behind a reverse proxy
|
||||
which would allow him or her to collect data from the client accesses, but even still,
|
||||
this is not something the instance has access to and therefore you won't either.
|
||||
|
||||
### Is the instance adminstrator able to view the contents of this box
|
||||
|
||||
Yes they are. Whether you trust the instance adminsitrator with these files is up to you.
|
||||
|
||||
### What can't be uploaded to these boxes?
|
||||
|
||||
This is up to the instance administrator to define. See [Uploading guidelines](/uploading-guidelines#).
|
||||
|
||||
### What happens if the instance administrator changes the max lifetime of a box or the maximum upload size?
|
||||
|
||||
If the max lifetime is changed your newly created box won't be affected and your lifetime will still be the same from when the
|
||||
box was created. If the instance administrator changes te maximum upload size, your configurations will be capped to
|
||||
conform to those changes. Make sure your configurations are up to date by downloading the `config.json5` from this box at
|
||||
every periodic change.
|
||||
|
||||
### Making changes to these files is hard on a mobile UwU, why can't I edit the configurations with a form?
|
||||
|
||||
Not our problem. Get a computer.
|
||||
|
||||
### Why json5?
|
||||
|
||||
YAML sucks. TOML sucks. JSON sucks. JSON5 sucks less. [Here's what it looks like](https://github.com/chromium/chromium/blob/feb3c9f670515edf9a88f185301cbd7794ee3e52/third_party/blink/renderer/platform/runtime_enabled_features.json5).
|
||||
Lua is an option and it actually rocks but that's a bit overkill for this project.
|
||||
|
||||
### What happens if I lose my edit code?
|
||||
|
||||
It's totally up to you to not do that.
|
||||
|
||||
<script>alert("if this is executed it means we screwed up")</script>
|
||||
256
views/template.templ
Normal file
256
views/template.templ
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
package views
|
||||
|
||||
import (
|
||||
"foobar/database"
|
||||
"foobar/model"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
templ indexLayout() {
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<title>Mude meu título!</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="htmx-config" content='{ "responseHandling":[{"code":"422", "swap": true}, {"code":"200", "swap": true}] }' />
|
||||
<!-- tailwind -->
|
||||
<link href="/static/css/output.css" rel="stylesheet"/>
|
||||
<!-- markdown styling -->
|
||||
<link href="/static/css/github-markdown.css" rel="stylesheet"/>
|
||||
<!-- daisyUI -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
||||
<!-- daisyUI Themes -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
||||
// <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||
<!-- HTMX -->
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||
<!-- Hyperscript -->
|
||||
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
|
||||
<style>
|
||||
html, body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="flex-wrap flex content-center justify-between flex-col bg-base-100 text-sm"
|
||||
hx-boost="true" hx-push-url="true" hx-target="this">
|
||||
{ children... }
|
||||
<footer></footer>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
||||
templ mainCenterBody() {
|
||||
@indexLayout() {
|
||||
<main class="w-full" >
|
||||
{ children... }
|
||||
</main>
|
||||
}
|
||||
}
|
||||
|
||||
const toggleButtonInMeUntilLoad =
|
||||
`on every htmx:beforeSend
|
||||
tell <button/> in me
|
||||
toggle [@disabled='true'] until htmx:afterOnLoad
|
||||
end
|
||||
end`
|
||||
|
||||
func safeURL(s string) string {
|
||||
return fmt.Sprint(templ.SafeURL(s))
|
||||
}
|
||||
|
||||
templ Index() {
|
||||
@mainCenterBody() {
|
||||
<div class="hero-content">
|
||||
<div class="max-w-md text-center">
|
||||
<h1>hakobox</h1>
|
||||
<p>nothing here...</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
templ boxUploadSidebar(boxURL model.BoxURL) {
|
||||
@mainCenterBody() {
|
||||
<div class="">
|
||||
<section class="static md:fixed top-0 left-0 z-10 w-full md:w-3/9 p-10 bg-base-200 h-full ">
|
||||
<header>
|
||||
<h1>hakobox</h1>
|
||||
<p>It's temporary file sharing but everyone gets to contribute! </p>
|
||||
<p class="leading-tight font-medium text-black">Drop in a file to be added to this box </p>
|
||||
</header>
|
||||
<form id="add-file"
|
||||
hx-trigger="submit"
|
||||
hx-post={safeURL(fmt.Sprintf("/box/%s", boxURL))}
|
||||
hx-encoding="multipart/form-data">
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Pick a file</legend>
|
||||
<input name="file" type="file" class="file-input" style="width: 100%;" multiple required/>
|
||||
<label class="fieldset-label">Max size 2MB</label>
|
||||
</fieldset>
|
||||
<fieldset class="fieldset">
|
||||
<legend class="fieldset-legend">Edit code</legend>
|
||||
<input type="text" class="input" name="edit_code" placeholder="Type here" style="width: 100%;"/>
|
||||
<p class="label">Optional</p>
|
||||
</fieldset>
|
||||
@errorTarget()
|
||||
<button type="submit" class="btn btn-primary mb-5">Add to the box!</button>
|
||||
<div class="text-center">
|
||||
<a class="link link-primary block mb-0"
|
||||
href={templ.SafeURL(fmt.Sprintf("/box/%s/inside", boxURL))}>
|
||||
See what's inside
|
||||
</a>
|
||||
<a class="link link-primary block mb-0"
|
||||
href={templ.SafeURL(fmt.Sprintf("/box/%s", boxURL))}>
|
||||
Front page
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<section class="md:px-20 p-4 md:my-40 m-0 md:ml-auto md:max-w-6/9">
|
||||
{ children... }
|
||||
</section>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ BoxUpload(box model.Box) {
|
||||
@boxUploadSidebar(box.Url()) {
|
||||
<div class="markdown-body">
|
||||
@templ.Raw(box.Header())
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ NewBox(boxURL model.BoxURL, templateReadme model.Markdown) {
|
||||
@boxUploadSidebar(boxURL) {
|
||||
<div class="markdown-body">
|
||||
@templ.Raw(templateReadme)
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
templ Box(boxURL model.BoxURL, files []model.File) {
|
||||
@boxUploadSidebar(boxURL) {
|
||||
<main class="inline-flex flex-wrap gap-0 md:gap-5 mt-20 w-full h-full justify-start md:justify-center">
|
||||
if len(files) == 0 {
|
||||
<h2 class="m-auto">Empty box.</h2>
|
||||
} else {
|
||||
for i := range files {
|
||||
@fileCard(files[i])
|
||||
}
|
||||
}
|
||||
</main>
|
||||
}
|
||||
}
|
||||
|
||||
func fileDisplay(file model.File) templ.Component {
|
||||
switch {
|
||||
case file.Mime().IsImage():
|
||||
return fileImageFigure(file)
|
||||
case file.Mime().IsVideo():
|
||||
return fileVideoFigure(file)
|
||||
default:
|
||||
return unknownFileFigure()
|
||||
// panic(fmt.Errorf("unrecognized mime: %s", file.Mime))
|
||||
}
|
||||
}
|
||||
|
||||
templ fileCard(file model.File) {
|
||||
<a class="card w-1/2 md:w-2xs aspect-square mb-10" href={templ.SafeURL(fmt.Sprintf("/static/box/%s", file.ID()))} target="_blank">
|
||||
<figure class="flex flex-col p-1 m-auto mb-auto md:mb-0 text-center">
|
||||
@fileDisplay(file)
|
||||
</figure>
|
||||
<div class="hidden md:inline font-light text-sm" style="text-wrap: nowrap;">
|
||||
<p title={file.Name()}>{shorten(file.Name())}</p>
|
||||
<p title={file.Name()}>{file.CreatedAt().Format(time.DateOnly)}</p>
|
||||
<p>{formatSize(file.Size())} {file.Mime().PrettyType()}</p>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
|
||||
templ fileImageFigure(file model.File) {
|
||||
<img
|
||||
title={file.Name()}
|
||||
loading="lazy"
|
||||
src={fmt.Sprintf("/static/box/%s", file.ID())}
|
||||
alt={file.Name()} />
|
||||
}
|
||||
|
||||
templ fileVideoFigure(file model.File) {
|
||||
<video title={file.Name()} loading="lazy" alt={file.Name()} >
|
||||
<source src={fmt.Sprintf("/static/box/%s", file.ID())}/>
|
||||
</video>
|
||||
}
|
||||
|
||||
|
||||
templ unknownFileFigure() {
|
||||
<div>unknown format!</div>
|
||||
}
|
||||
|
||||
|
||||
func shorten(text string) string {
|
||||
if len(text) > 41 {
|
||||
return fmt.Sprintf("%s...", text[:41-3])
|
||||
} else {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
func formatSize(size int64) string {
|
||||
units := []string{"b", "Kb", "Mb", "Gb"}
|
||||
i := 0
|
||||
fSize := float64(size)
|
||||
for fSize >= 1000 && i < len(units)-1 {
|
||||
fSize /= 1000
|
||||
i++
|
||||
}
|
||||
return fmt.Sprintf("%.2f %s", fSize, units[i])
|
||||
}
|
||||
|
||||
templ FourOfour() {
|
||||
@indexLayout() {
|
||||
<div>404</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ Logged(usuario *database.Usuario) {
|
||||
@indexLayout() {
|
||||
<p>Logado como: { usuario.Nome }</p>
|
||||
<div style="text-align: center;">
|
||||
<p>
|
||||
<a href="/">index</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/logout">logout</a>
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ errorTarget() {
|
||||
<div id="error-target">
|
||||
</div>
|
||||
}
|
||||
|
||||
templ ErrorBox(msg string) {
|
||||
<div role="alert" class="bounce mt-3 relative flex flex-col w-full p-3 text-sm text-white bg-red-600 rounded-md">
|
||||
<p class="flex text-base">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="h-5 w-5 mr-2 mt-0.5"><path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"></path></svg>
|
||||
Error
|
||||
</p>
|
||||
<p class="ml-4 p-3">
|
||||
{ msg }
|
||||
</p>
|
||||
|
||||
<button class="flex items-center justify-center transition-all w-8 h-8 rounded-md text-white hover:bg-white/10 active:bg-white/10 absolute top-1.5 right-1.5" type="button"
|
||||
_='on click tell closest <div[role="alert"]/> transition opacity to 0 then remove yourself end'
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="h-5 w-5" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue