File manager mockup
This commit is contained in:
@@ -55,7 +55,7 @@ function listCreated(response){
|
||||
+ "</div>";
|
||||
|
||||
$('#uploads_queue').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
$(resultString).hide().fadeIn('slow').css("display", "")
|
||||
);
|
||||
window.open('/l/'+response.id, '_blank');
|
||||
}else{
|
||||
@@ -65,7 +65,7 @@ function listCreated(response){
|
||||
+ "</div>";
|
||||
|
||||
$('#uploads_queue').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
$(resultString).hide().fadeIn('slow').css("display", "")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -133,14 +133,8 @@ hr{
|
||||
::-webkit-scrollbar-thumb {background-color: #555;}
|
||||
::-webkit-scrollbar-corner{background: transparent;}
|
||||
|
||||
a{
|
||||
color: var(--highlight_color);
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover{
|
||||
text-decoration: underline;
|
||||
color: var(--highlight_color);
|
||||
}
|
||||
a {color: var(--highlight_color); text-decoration: none;}
|
||||
a:hover {color: var(--highlight_color); text-decoration: underline;}
|
||||
|
||||
.form{
|
||||
margin-left: auto;
|
||||
@@ -243,10 +237,13 @@ pre{
|
||||
|
||||
/* BUTTONS */
|
||||
button,
|
||||
.button,
|
||||
input[type="submit"],
|
||||
input[type="button"],
|
||||
input[type="color"],
|
||||
select{
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
margin: 2px;
|
||||
@@ -254,24 +251,33 @@ select{
|
||||
padding: 6px 10px 6px 10px;
|
||||
box-shadow: 2px 2px 8px #000000;
|
||||
font-weight: bold;
|
||||
font-size: 0.85em;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
color: #FFFFFF;
|
||||
outline: 0;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
button:hover,
|
||||
.button:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="button"]:hover,
|
||||
input[type="color"]:hover,
|
||||
select:hover,
|
||||
button:focus,
|
||||
.button:focus,
|
||||
input[type="submit"]:focus,
|
||||
input[type="button"]:focus,
|
||||
input[type="color"]:focus,
|
||||
select:focus{
|
||||
color: #FFFFFF;
|
||||
text-decoration: none;
|
||||
box-shadow: var(--highlight_border), 2px 2px 8px #000000;
|
||||
}
|
||||
button:active,
|
||||
.button:active,
|
||||
input[type="submit"]:active,
|
||||
input[type="button"]:active,
|
||||
input[type="color"]:active,
|
||||
@@ -291,6 +297,7 @@ option{background-color: #404040; color: #FFFFFF;}
|
||||
|
||||
/* TEXT FIELDS */
|
||||
textarea,
|
||||
.groove,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
|
@@ -3,20 +3,63 @@
|
||||
<head>
|
||||
{{template "meta_tags" "File Manager"}}
|
||||
<script type="text/javascript">var apiEndpoint = '{{.APIEndpoint}}';</script>
|
||||
<style>
|
||||
.file_manager {
|
||||
position: absolute;
|
||||
padding: 0px 8px 0px 8px;
|
||||
background-color: #252525;
|
||||
box-shadow: #000000 8px 8px 50px 5px;
|
||||
left:100px;
|
||||
top:100px;
|
||||
right: 100px;
|
||||
min-width: 600px;
|
||||
max-width: 1400px;
|
||||
}
|
||||
.file_manager > .nav_bar {
|
||||
display: flex;
|
||||
flex-direction: row
|
||||
}
|
||||
.file_manager > .nav_bar :first-child {margin-left: 5px;}
|
||||
.file_manager > .nav_bar :last-child {margin-right: 5px;}
|
||||
.file_manager > .nav_bar > button {flex: 0;}
|
||||
.file_manager > .nav_bar > .breadcrumbs {flex: 1; margin: 1px 10px; min-width: 100px;}
|
||||
.file_manager > .status_bar {text-align: left;}
|
||||
|
||||
.file_button {height: 40px !important;}
|
||||
.file_button > img {max-height: 40px !important;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
|
||||
<br/>
|
||||
{{range .Other.Files}}
|
||||
<div class="file_manager">
|
||||
<div class="nav_bar highlight_light border_top border_bottom">
|
||||
<button>⇐</button>
|
||||
<button>⇑</button>
|
||||
<button style="margin-right: 16px;">⇒</button>
|
||||
<button>🏠</button>
|
||||
<input class="breadcrumbs" type="text" value="/{{.Username}}/Documents"/>
|
||||
<button>↻</button>
|
||||
<button>🔎</button>
|
||||
<button style="margin-left: 16px;">_</button>
|
||||
<button>☐</button>
|
||||
<button class="button_red">✕</button>
|
||||
</div>
|
||||
<div class="directory_area">
|
||||
{{$files := .PixelAPI.UserFiles 0 20}}
|
||||
{{range $files.Files}}
|
||||
<a class="file_button" href="/u/{{.ID}}" target="_blank">
|
||||
<img src="{{$.APIEndpoint}}/file/{{.ID}}/thumbnail" alt="{{.FileName}}" />
|
||||
<span style="color: var(--highlight_color);">{{.FileName}}</span>
|
||||
<br/>
|
||||
{{.DateUpload}}
|
||||
{{.FileName}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="status_bar highlight_light border_top border_bottom">
|
||||
13 items (5 directories, 7 files). Total size: 1.23 GB
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
|
@@ -49,12 +49,10 @@
|
||||
|
||||
<!--Views: <span id="views" th:text="${data.views}">0</span>--><br/>
|
||||
|
||||
<form action="/" target="_self">
|
||||
<button id="btnHome" class="toolbar_button button_full_width">
|
||||
<a href="/" id="btnHome" class="button toolbar_button button_full_width">
|
||||
<img src="/res/img/pixeldrain_small.png" alt="Back to the Home page"/>
|
||||
<span>Home</span>
|
||||
</button>
|
||||
</form>
|
||||
</a>
|
||||
|
||||
<button id="btnDownload" class="toolbar_button button_full_width" onClick="Toolbar.download();">
|
||||
<img src="/res/img/floppy_small.png" alt="Download this file"/>
|
||||
|
@@ -36,7 +36,7 @@
|
||||
The Sia integration is still very experimental and could
|
||||
fail, resulting in data loss. Do not upload files to this server
|
||||
that you cannot afford to lose. Use the stable main server instead:
|
||||
<a href="https://pixeldrain.com">https://pixeldrain.com</a>.
|
||||
<a class="button" href="https://pixeldrain.com">https://pixeldrain.com</a>.
|
||||
</p>
|
||||
<p>
|
||||
But don't let all that stop you from trying the new Pixeldrain!
|
||||
|
@@ -30,11 +30,10 @@
|
||||
<img src="/res/img/upload_small.png" alt="Start Upload"/>
|
||||
<span>Upload</span>
|
||||
</button>
|
||||
<form action="/">
|
||||
<button class="toolbar_button button_full_width">
|
||||
<a href="/" class="button toolbar_button button_full_width">
|
||||
<img src="/res/img/pixeldrain_small.png" alt="Visit the home page" style="width:22px; height: 22px;"/>
|
||||
<span>Home</span>
|
||||
</button>
|
||||
</a>
|
||||
</form>
|
||||
<iframe id='sponsors' data-aa='73974'
|
||||
src='//ad.a-ads.com/73974?size=120x600&background_color=000000&text_color=eeeeee&title_color=eeeeee&link_color=9fcf6c&link_hover_color=d2ffa1&title_hover_color=d2ffa1'
|
||||
|
@@ -23,21 +23,21 @@ func (wc *WebController) serveFilePreview(w http.ResponseWriter, r *http.Request
|
||||
serveFilePreviewDemo(w) // Required for a-ads.com quality check
|
||||
return
|
||||
}
|
||||
|
||||
inf, err := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling
|
||||
var api = pixelapi.New(wc.conf.APIURLInternal, "")
|
||||
inf, err := api.GetFileInfo(p.ByName("id")) // TODO: Error handling
|
||||
if err != nil {
|
||||
wc.serveNotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
var fp = FilePreview{
|
||||
var fp = filePreview{
|
||||
APIURL: wc.conf.APIURLExternal,
|
||||
PixelAPI: wc.api,
|
||||
PixelAPI: api,
|
||||
}
|
||||
io.WriteString(w, fp.Run(inf))
|
||||
io.WriteString(w, fp.run(inf))
|
||||
}
|
||||
|
||||
type FilePreview struct {
|
||||
type filePreview struct {
|
||||
FileInfo *pixelapi.FileInfo
|
||||
FileURL string
|
||||
DownloadURL string
|
||||
@@ -46,7 +46,7 @@ type FilePreview struct {
|
||||
PixelAPI *pixelapi.PixelAPI
|
||||
}
|
||||
|
||||
func (f FilePreview) Run(inf *pixelapi.FileInfo) string {
|
||||
func (f filePreview) run(inf *pixelapi.FileInfo) string {
|
||||
f.FileInfo = inf
|
||||
f.FileURL = f.APIURL + "/file/" + f.FileInfo.ID
|
||||
f.DownloadURL = f.APIURL + "/file/" + f.FileInfo.ID + "/download"
|
||||
@@ -92,7 +92,7 @@ func (f FilePreview) Run(inf *pixelapi.FileInfo) string {
|
||||
return f.def()
|
||||
}
|
||||
|
||||
func (f FilePreview) image() string {
|
||||
func (f filePreview) image() string {
|
||||
return fmt.Sprintf(`<div class="image-container">
|
||||
<img id="displayImg" src="%s" class="pannable drop-shadow"/>
|
||||
</div>
|
||||
@@ -100,7 +100,7 @@ func (f FilePreview) image() string {
|
||||
f.FileURL)
|
||||
}
|
||||
|
||||
func (f FilePreview) audio() string {
|
||||
func (f filePreview) audio() string {
|
||||
return fmt.Sprintf(`<div class="image-container">
|
||||
<br/><br/>
|
||||
<img src="/res/img/mime/audio.png" alt="Audio"/>
|
||||
@@ -115,7 +115,7 @@ func (f FilePreview) audio() string {
|
||||
)
|
||||
}
|
||||
|
||||
func (f FilePreview) video() string {
|
||||
func (f filePreview) video() string {
|
||||
return fmt.Sprintf(`<div class="image-container">
|
||||
<video id="videoPlayer" autoplay="autoplay" controls="controls" class="center drop-shadow">
|
||||
<source src="%s"/>
|
||||
@@ -128,12 +128,12 @@ Your web browser does not support the HTML video tag.
|
||||
|
||||
}
|
||||
|
||||
func (f FilePreview) pdf() string {
|
||||
func (f filePreview) pdf() string {
|
||||
u, _ := url.Parse(f.FileURL)
|
||||
return f.frame("/res/misc/pdf-viewer/web/viewer.html?file=" + u.String())
|
||||
}
|
||||
|
||||
func (f FilePreview) text() string {
|
||||
func (f filePreview) text() string {
|
||||
htmlOut := `<div class="text-container">
|
||||
<pre class="pre-container %s" style="width: 100%%;">%s</pre>
|
||||
</div>`
|
||||
@@ -180,7 +180,7 @@ func (f FilePreview) text() string {
|
||||
return fmt.Sprintf(htmlOut, prettyPrint, result)
|
||||
}
|
||||
|
||||
func (f FilePreview) frame(url string) string {
|
||||
func (f filePreview) frame(url string) string {
|
||||
return fmt.Sprintf(`<iframe src="%s" class="image-container"
|
||||
seamless="seamless" frameborder="0" allowtransparency="true"
|
||||
</iframe>`,
|
||||
@@ -188,7 +188,7 @@ seamless="seamless" frameborder="0" allowtransparency="true"
|
||||
)
|
||||
}
|
||||
|
||||
func (f FilePreview) def() string {
|
||||
func (f filePreview) def() string {
|
||||
return fmt.Sprintf(
|
||||
`%s<br/>%s<br/><a href="%s"><img src="%s" class="image"></a>`,
|
||||
f.FileInfo.FileName,
|
||||
|
@@ -26,9 +26,10 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
ids = append(ids, p.ByName("id"))
|
||||
}
|
||||
|
||||
var api = pixelapi.New(wc.conf.APIURLInternal, "")
|
||||
var finfo []*pixelapi.FileInfo
|
||||
for _, id := range ids {
|
||||
inf, err := wc.api.GetFileInfo(id)
|
||||
inf, err := api.GetFileInfo(id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@@ -12,7 +12,8 @@ import (
|
||||
|
||||
// ServeListViewer controller for GET /l/:id
|
||||
func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var list, err = wc.api.GetList(p.ByName("id"))
|
||||
var api = pixelapi.New(wc.conf.APIURLInternal, "")
|
||||
var list, err = api.GetList(p.ByName("id"))
|
||||
if err != nil {
|
||||
if (err.(pixelapi.Error)).ReqError {
|
||||
log.Error("API request error occurred: %s", (err.(pixelapi.Error)).Value)
|
||||
|
@@ -7,25 +7,26 @@ import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"fornaxian.com/pixeldrain-web/init/conf"
|
||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||
"fornaxian.com/pixeldrain-web/webcontroller/templates"
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
// WebController controls how requests are handled and makes sure they have
|
||||
// proper context when running
|
||||
type WebController struct {
|
||||
conf *conf.PixelWebConfig
|
||||
api *pixelapi.PixelAPI // Shared instance, only used for unauthenticated requests
|
||||
templates *templates.TemplateManager
|
||||
staticResourceDir string
|
||||
}
|
||||
|
||||
// New initializes a new WebController by registering all the request handlers
|
||||
// and parsing all templates in the resource directory
|
||||
func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebController {
|
||||
var wc = &WebController{
|
||||
conf: conf,
|
||||
staticResourceDir: conf.StaticResourceDir,
|
||||
}
|
||||
wc.api = pixelapi.New(conf.APIURLInternal, "")
|
||||
wc.templates = templates.New(
|
||||
conf.TemplateDir,
|
||||
conf.APIURLExternal,
|
||||
@@ -36,22 +37,25 @@ func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebCon
|
||||
// Serve static files
|
||||
r.ServeFiles(prefix+"/res/*filepath", http.Dir(wc.staticResourceDir+"/res"))
|
||||
|
||||
// General navigation
|
||||
r.GET(prefix+"/" /* */, wc.serveTemplate("home", false))
|
||||
r.GET(prefix+"/favicon.ico" /* */, wc.serveFile("/favicon.ico"))
|
||||
r.GET(prefix+"/global.css" /* */, wc.globalCSSHandler)
|
||||
r.GET(prefix+"/api" /* */, wc.serveTemplate("apidoc", false))
|
||||
r.GET(prefix+"/history" /* */, wc.serveTemplate("history_cookies", false))
|
||||
r.GET(prefix+"/u/:id" /* */, wc.serveFileViewer)
|
||||
r.GET(prefix+"/u/:id/preview" /**/, wc.serveFilePreview)
|
||||
r.GET(prefix+"/u/:id/preview" /* */, wc.serveFilePreview)
|
||||
r.GET(prefix+"/l/:id" /* */, wc.serveListViewer)
|
||||
r.GET(prefix+"/t" /* */, wc.serveTemplate("paste", false))
|
||||
|
||||
// User account pages
|
||||
r.GET(prefix+"/register" /* */, wc.serveTemplate("register", false))
|
||||
r.GET(prefix+"/login" /* */, wc.serveTemplate("login", false))
|
||||
r.GET(prefix+"/logout" /* */, wc.serveTemplate("logout", true))
|
||||
r.POST(prefix+"/logout" /* */, wc.serveLogout)
|
||||
r.GET(prefix+"/user" /* */, wc.serveTemplate("user_home", true))
|
||||
r.GET(prefix+"/user/files" /* */, wc.serveTemplate("user_files", true))
|
||||
r.GET(prefix+"/user/filemanager" /**/, wc.serveTemplate("file_manager", true))
|
||||
|
||||
r.NotFound = http.HandlerFunc(wc.serveNotFound)
|
||||
|
||||
|
Reference in New Issue
Block a user