albums: basic support (json array using contented/album mime-type)
This commit is contained in:
parent
156e2ab540
commit
4294738337
@ -22,6 +22,8 @@ var SERVER_HEADER string = `contented/0.0.0-dev`
|
||||
|
||||
const DEFAULT_MAX_CONCURRENT_THUMBS = 16
|
||||
|
||||
const ALBUM_MIMETYPE = `contented/album`
|
||||
|
||||
type ServerPublicProperties struct {
|
||||
AppTitle string
|
||||
MaxUploadBytes int64
|
||||
|
58
preview.go
58
preview.go
@ -1,11 +1,13 @@
|
||||
package contented
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -56,6 +58,19 @@ html, body {
|
||||
line-height: 0;
|
||||
width: 340px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.thumbnail-overlay {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
padding: 4px 8px;
|
||||
line-height: 1.5em;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
||||
.properties {
|
||||
background: #000;
|
||||
@ -82,6 +97,48 @@ html, body {
|
||||
return
|
||||
}
|
||||
|
||||
if m.MimeType == ALBUM_MIMETYPE {
|
||||
// Special handling for albums
|
||||
f, err := os.Open(filepath.Join(this.opts.DataDirectory, m.FileHash))
|
||||
if err != nil {
|
||||
log.Printf("Opening file '%s' for preview of album '%s': %s", m.FileHash, fileID, err.Error())
|
||||
http.Error(w, "Internal error", 500)
|
||||
return
|
||||
}
|
||||
|
||||
var childIDs []string
|
||||
err = json.NewDecoder(f).Decode(&childIDs)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
log.Printf("Failed to parse album '%s': %s", fileID, err)
|
||||
http.Error(w, "Internal error", 500)
|
||||
return
|
||||
}
|
||||
|
||||
if len(childIDs) == 0 {
|
||||
log.Printf("Failed to parse album '%s': no entries in album", fileID)
|
||||
http.Error(w, "Internal error", 500)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl += `
|
||||
<div class="entry">
|
||||
<div class="thumbnail">
|
||||
<a href="` + html.EscapeString(`/p/`+strings.Join(childIDs, `-`)) + `"><img src="` + html.EscapeString(`/thumb/m/`+childIDs[0]) + `"></a>
|
||||
<div class="thumbnail-overlay">` + fmt.Sprintf("%d", len(childIDs)) + ` image(s)</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<b>Name:</b> ` + html.EscapeString(m.Filename) + `<br>
|
||||
<b>Hash:</b> <span title="` + html.EscapeString(m.FileHash) + `">hover</span><br>
|
||||
<b>File type:</b> Album<br>
|
||||
<b>Size:</b> ` + fmt.Sprintf("%d", len(childIDs)) + ` image(s)<br>
|
||||
<b>Uploader:</b> ` + html.EscapeString(m.UploadIP) + `<br>
|
||||
<b>Uploaded at:</b> ` + html.EscapeString(m.UploadTime.Format(time.RFC3339)) + `<br>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
} else {
|
||||
tmpl += `
|
||||
<div class="entry">
|
||||
<div class="thumbnail">
|
||||
@ -98,6 +155,7 @@ html, body {
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
if this.opts.EnableHomepage {
|
||||
tmpl += `
|
||||
|
@ -178,6 +178,12 @@
|
||||
<path fill="#000000" d="M16.84,2.73C16.45,2.73 16.07,2.88 15.77,3.17L13.65,5.29L18.95,10.6L21.07,8.5C21.67,7.89 21.67,6.94 21.07,6.36L17.9,3.17C17.6,2.88 17.22,2.73 16.84,2.73M12.94,6L4.84,14.11L7.4,14.39L7.58,16.68L9.86,16.85L10.15,19.41L18.25,11.3M4.25,15.04L2.5,21.73L9.2,19.94L8.96,17.78L6.65,17.61L6.47,15.29" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="contented-upload-type" data-upload-type="album" title="Album">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M3,3H21V7H3V3M4,8H20V21H4V8M9.5,11A0.5,0.5 0 0,0 9,11.5V13H15V11.5A0.5,0.5 0 0,0 14.5,11H9.5Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="contented-content-area">
|
||||
@ -204,6 +210,15 @@
|
||||
<label>...</label>
|
||||
<div class="contented-progress-bar"><div class="contented-progress-element"></div></div>
|
||||
</div>
|
||||
|
||||
<div class="contented-upload-if contented-if-album">
|
||||
<label>
|
||||
Type a list of short IDs, separated with commas:<br>
|
||||
<input class="contented-album-input" type="text">
|
||||
</label>
|
||||
<br><br>
|
||||
<button class="contented-album-upload">Make album »</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -307,6 +322,32 @@
|
||||
handleUploadFrom([blob]);
|
||||
});
|
||||
|
||||
// Album
|
||||
|
||||
$f.find(".contented-album-upload").on("click", function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var childIDs = $(".contented-album-input").val().split(",");
|
||||
|
||||
for (var i = 0; i < childIDs.length; ++i) {
|
||||
childIDs[i] = childIDs[i].trim(); // Basic validation - can't really perform full validation here
|
||||
|
||||
if (childIDs[i].length == 0) {
|
||||
alert("Entry " + (i+1) + " is too short, expected non-zero length");
|
||||
return;
|
||||
}
|
||||
|
||||
if (! childIDs[i].match(/^[a-zA-Z0-9]+$/)) {
|
||||
alert("Entry " + (i+1) + " contains unexpected character");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var blob = new Blob([JSON.stringify(childIDs)], {type : 'contented/album'});
|
||||
handleUploadFrom([blob]);
|
||||
});
|
||||
|
||||
// Ctrl+V uploads
|
||||
|
||||
var pasteHandler = function(e) {
|
||||
|
Loading…
Reference in New Issue
Block a user