support skynet
This commit is contained in:
16
go.mod
16
go.mod
@@ -6,24 +6,10 @@ require (
|
||||
fornaxian.com/pixeldrain-api v0.0.0-20191216095319-0533f903c681
|
||||
github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70
|
||||
github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/k0kubun/pp v3.0.1+incompatible // indirect
|
||||
github.com/kisielk/gotool v1.0.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.11 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.2
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 // indirect
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab // indirect
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/spf13/cobra v0.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8
|
||||
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 // indirect
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 // indirect
|
||||
golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2 // indirect
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0
|
||||
)
|
||||
|
32
go.sum
32
go.sum
@@ -10,6 +10,10 @@ github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70 h1:yRkXab8h+BAWEp
|
||||
github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70/go.mod h1:Ig5am30IOP/eqsjogI1TuSlOTIeTPHoMOpYYM1bisww=
|
||||
github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3 h1:PfKr7anK3z4kLG9V6BbbKOVFhVaGEAJi4HxXCAa+QeU=
|
||||
github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3/go.mod h1:jdnyerqAlXJJpQmpyrdmSYMitRaRZ8RejEXuXz6n5QY=
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204164318-fc5d8b4479f9 h1:8cg0suW9Ny88xGYnaFyfXG5CH7Vxu8jm8PAwnZM4JOk=
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204164318-fc5d8b4479f9/go.mod h1:Ew6h8nlacK6H8aABMDUYN3uaO4Rpw2HLKQZ2ntEybqM=
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145 h1:2a8cFtVwEvK7NeimwAEoSUdf4hC80cXpnj3s4pHga+c=
|
||||
github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145/go.mod h1:Ew6h8nlacK6H8aABMDUYN3uaO4Rpw2HLKQZ2ntEybqM=
|
||||
github.com/Fornaxian/unifilter v0.0.0-20180623154047-e65e144d5942/go.mod h1:ofV5syadd2nI4gOc/rP1yPnXkARgm+E1D/U38mbUj44=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
@@ -17,6 +21,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/threefish v0.0.0-20120919164726-3ecf4c494abf/go.mod h1:bXVurdTuvOiJu7NHALemFe0JMvC2UmwYHW+7fcZaZ2M=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
@@ -25,6 +30,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU=
|
||||
@@ -45,6 +51,9 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -67,9 +76,12 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
@@ -86,7 +98,9 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8 h1:gw/M1/pCu7oELGHZ6rvktNmMbdWhf9kHc7WYrbLeKdo=
|
||||
github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8/go.mod h1:oqLl90kSlp4+8wMQKql9ZdQGa4/5pVCxOOpTVWkoyV0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
@@ -104,6 +118,7 @@ gitlab.com/NebulousLabs/threadgroup v0.0.0-20180716154133-88a11db9e46c/go.mod h1
|
||||
gitlab.com/NebulousLabs/writeaheadlog v0.0.0-20190703190009-cb822c37bc94/go.mod h1:Lhpa9AcbWcYKcc4amZsOHqJdQglnkWrGuUI68XC7U2Q=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||
@@ -112,13 +127,17 @@ golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9Q
|
||||
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -135,11 +154,24 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2 h1:FAGfnR+fyptW02iTeG8Lytc+6v8yqyQJIx/JMZhMA5M=
|
||||
golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130224948-02f1738cbe39 h1:5ERHXLQfA0b8cHOwaOfWaaGekrA4+Ka/N74zilLnsIk=
|
||||
golang.org/x/tools v0.0.0-20200130224948-02f1738cbe39/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
|
||||
golang.org/x/tools/gopls v0.3.0 h1:l9KKK1/n6CIbfgaUvHBWAvCfOxcl1N+KSOK79OlPIao=
|
||||
golang.org/x/tools/gopls v0.3.0/go.mod h1:vvBkm7WBjHNudDeK7Sg7HeR+sKt6yp5TD/4NQaTZzRs=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0 h1:+FlnIV8DSQnT7NZ43hcVKcdJdzZoeCmJj4Ql8gq5keA=
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0/go.mod h1:6sSBNz/GtOm/pJTuh5UmBK2ZHfmnxGbl2NZg1UliSOI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
mvdan.cc/xurls/v2 v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA=
|
||||
mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E=
|
||||
|
@@ -7,11 +7,12 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
|
||||
var client = &http.Client{}
|
||||
var client = &http.Client{Timeout: time.Minute * 5}
|
||||
|
||||
// PixelAPI is the Pixeldrain API client
|
||||
type PixelAPI struct {
|
||||
|
@@ -22,6 +22,17 @@ function addUploadHistory(fileID) {
|
||||
localStorage.setItem("uploaded_files", fileID + "," + uploads);
|
||||
}
|
||||
|
||||
function printDate(date, hours, minutes, seconds) {
|
||||
let dateStr = date.getFullYear()
|
||||
+"-"+("00"+(date.getMonth()+1)).slice(-2)
|
||||
+"-"+("00"+date.getDate()).slice(-2)
|
||||
|
||||
if (hours) { dateStr += " "+("00"+date.getHours()).slice(-2) }
|
||||
if (minutes) { dateStr += ":"+("00"+date.getMinutes()).slice(-2) }
|
||||
if (seconds) { dateStr += ":"+("00"+date.getMinutes()).slice(-2) }
|
||||
return dateStr
|
||||
}
|
||||
|
||||
function copyText(text) {
|
||||
// Create a textarea to copy the text from
|
||||
let ta = document.createElement("textarea");
|
||||
|
@@ -190,12 +190,7 @@ DirectoryElement.prototype.createFileButton = function(file, index) {
|
||||
let cell = document.createElement("div")
|
||||
cell.style.width = this.fieldDateWidth
|
||||
let label = document.createElement("span")
|
||||
let date = new Date(file.dateCreated)
|
||||
label.innerText = date.getFullYear()
|
||||
+"-"+("00"+(date.getMonth()+1)).slice(-2)
|
||||
+"-"+("00"+date.getDate()).slice(-2)
|
||||
+" "+("00"+date.getHours()).slice(-2)
|
||||
+":"+("00"+date.getMinutes()).slice(-2)
|
||||
label.innerText = printDate(new Date(file.dateCreated), true, true, false)
|
||||
cell.appendChild(label)
|
||||
el.appendChild(cell)
|
||||
}
|
||||
|
@@ -1,86 +1,86 @@
|
||||
function DetailsWindow(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.visible = false;
|
||||
this.fileID = "";
|
||||
this.graph = 0;
|
||||
this.viewer = viewer
|
||||
this.visible = false
|
||||
this.fileID = ""
|
||||
this.graph = 0
|
||||
|
||||
this.divPopup = document.getElementById("details_popup");
|
||||
this.btnDetails = document.getElementById("btn_details");
|
||||
this.btnCloseDetails = document.getElementById("btn_close_details");
|
||||
this.divFileDetails = document.getElementById("info_file_details");
|
||||
this.divPopup = document.getElementById("details_popup")
|
||||
this.btnDetails = document.getElementById("btn_details")
|
||||
this.btnCloseDetails = document.getElementById("btn_close_details")
|
||||
this.divFileDetails = document.getElementById("info_file_details")
|
||||
|
||||
this.btnDetails.addEventListener("click", () => { this.toggle(); });
|
||||
this.btnCloseDetails.addEventListener("click", () => { this.toggle(); });
|
||||
this.btnDetails.addEventListener("click", () => { this.toggle() })
|
||||
this.btnCloseDetails.addEventListener("click", () => { this.toggle() })
|
||||
}
|
||||
|
||||
DetailsWindow.prototype.toggle = function() {
|
||||
if (this.visible) {
|
||||
this.divPopup.style.opacity = "0";
|
||||
this.divPopup.style.visibility = "hidden";
|
||||
this.btnDetails.classList.remove("button_highlight");
|
||||
this.visible = false;
|
||||
this.divPopup.style.opacity = "0"
|
||||
this.divPopup.style.visibility = "hidden"
|
||||
this.btnDetails.classList.remove("button_highlight")
|
||||
this.visible = false
|
||||
} else {
|
||||
this.divPopup.style.opacity = "1";
|
||||
this.divPopup.style.visibility = "visible";
|
||||
this.btnDetails.classList.add("button_highlight");
|
||||
this.visible = true;
|
||||
this.divPopup.style.opacity = "1"
|
||||
this.divPopup.style.visibility = "visible"
|
||||
this.btnDetails.classList.add("button_highlight")
|
||||
this.visible = true
|
||||
|
||||
// This is a workaround for a chrome bug which makes it so hidden
|
||||
// windows can't be scrolled after they are shown
|
||||
this.divPopup.focus();
|
||||
this.divPopup.focus()
|
||||
|
||||
if (this.graph === 0) {
|
||||
this.renderGraph();
|
||||
this.renderGraph()
|
||||
}
|
||||
this.updateGraph(this.fileID);
|
||||
this.updateGraph(this.fileID)
|
||||
}
|
||||
}
|
||||
|
||||
DetailsWindow.prototype.setDetails = function(file) {
|
||||
let desc = "";
|
||||
let desc = ""
|
||||
if (this.viewer.isList) {
|
||||
desc = file.description;
|
||||
desc = file.description
|
||||
}
|
||||
this.fileID = file.id;
|
||||
this.fileID = file.id
|
||||
this.divFileDetails.innerHTML = "<table>"
|
||||
+ "<tr><td>Name<td><td>" + escapeHTML(file.name) + "</td></tr>"
|
||||
+ "<tr><td>URL<td><td><a href=\"/u/" + file.id + "\">"+domainURL()+"/u/" + file.id + "</a></td></tr>"
|
||||
+ "<tr><td>URL<td><td><a href=\""+file.link+"\">"+file.link+"</a></td></tr>"
|
||||
+ "<tr><td>Mime Type<td><td>" + escapeHTML(file.mime_type) + "</td></tr>"
|
||||
+ "<tr><td>ID<td><td>" + file.id + "</td></tr>"
|
||||
+ "<tr><td>Size<td><td>" + formatDataVolume(file.size, 4) + "</td></tr>"
|
||||
+ "<tr><td>Bandwidth<td><td>" + formatDataVolume(file.bandwidth_used, 4) + "</td></tr>"
|
||||
+ "<tr><td>Upload Date<td><td>" + file.date_upload + "</td></tr>"
|
||||
+ "<tr><td>Upload Date<td><td>" + printDate(file.date_created, true, true, true) + "</td></tr>"
|
||||
+ "<tr><td>Description<td><td>" + escapeHTML(desc) + "</td></tr>"
|
||||
+ "</table>";
|
||||
+ "</table>"
|
||||
|
||||
if(this.visible) {
|
||||
this.updateGraph(file.id);
|
||||
if(this.visible && file.timeseries_href !== "") {
|
||||
this.updateGraph(file)
|
||||
}
|
||||
}
|
||||
|
||||
DetailsWindow.prototype.updateGraph = function(fileID) {
|
||||
console.log("updating graph "+fileID);
|
||||
fetch(apiEndpoint+"/file/" + fileID + "/timeseries?interval=60?days=14").then(resp => {
|
||||
if (!resp.ok) {return null;}
|
||||
return resp.json();
|
||||
DetailsWindow.prototype.updateGraph = function(file) {
|
||||
console.log("updating graph")
|
||||
fetch(file.timeseries_href+"?interval=60?days=14").then(resp => {
|
||||
if (!resp.ok) {return null}
|
||||
return resp.json()
|
||||
}).then(resp => {
|
||||
this.graph.data.labels = resp.labels;
|
||||
this.graph.data.datasets[0].data = resp.downloads;
|
||||
this.graph.data.datasets[1].data = resp.views;
|
||||
this.graph.update();
|
||||
this.graph.data.labels = resp.labels
|
||||
this.graph.data.datasets[0].data = resp.downloads
|
||||
this.graph.data.datasets[1].data = resp.views
|
||||
this.graph.update()
|
||||
})
|
||||
}
|
||||
|
||||
DetailsWindow.prototype.renderGraph = function() {
|
||||
console.log("rendering graph");
|
||||
Chart.defaults.global.defaultFontColor = "#b3b3b3";
|
||||
Chart.defaults.global.defaultFontSize = 15;
|
||||
Chart.defaults.global.defaultFontFamily = "Ubuntu";
|
||||
Chart.defaults.global.aspectRatio = 2.5;
|
||||
Chart.defaults.global.elements.point.radius = 0;
|
||||
Chart.defaults.global.tooltips.mode = "index";
|
||||
Chart.defaults.global.tooltips.axis = "x";
|
||||
Chart.defaults.global.tooltips.intersect = false;
|
||||
console.log("rendering graph")
|
||||
Chart.defaults.global.defaultFontColor = "#b3b3b3"
|
||||
Chart.defaults.global.defaultFontSize = 15
|
||||
Chart.defaults.global.defaultFontFamily = "Ubuntu"
|
||||
Chart.defaults.global.aspectRatio = 2.5
|
||||
Chart.defaults.global.elements.point.radius = 0
|
||||
Chart.defaults.global.tooltips.mode = "index"
|
||||
Chart.defaults.global.tooltips.axis = "x"
|
||||
Chart.defaults.global.tooltips.intersect = false
|
||||
this.graph = new Chart(
|
||||
document.getElementById('bandwidth_chart'),
|
||||
{
|
||||
@@ -148,5 +148,5 @@ DetailsWindow.prototype.renderGraph = function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
)
|
||||
}
|
||||
|
@@ -1,178 +1,178 @@
|
||||
function ListNavigator(viewer, files) {
|
||||
this.viewer = viewer;
|
||||
this.files = files;
|
||||
this.length = files.length;
|
||||
this.position = 0;
|
||||
this.history = [];
|
||||
this.shuffle = false;
|
||||
this.viewer = viewer
|
||||
this.files = files
|
||||
this.length = files.length
|
||||
this.position = 0
|
||||
this.history = []
|
||||
this.shuffle = false
|
||||
|
||||
this.divListNavigator = document.getElementById("list_navigator");
|
||||
this.divListNavigator = document.getElementById("list_navigator")
|
||||
|
||||
this.btnDownloadList = document.getElementById("btn_download_list");
|
||||
this.btnDownloadList = document.getElementById("btn_download_list")
|
||||
if (files.id !== "") {
|
||||
this.btnDownloadList.style.display = "";
|
||||
this.btnDownloadList.addEventListener("click", () => { this.downloadList(); });
|
||||
this.btnDownloadList.style.display = ""
|
||||
this.btnDownloadList.addEventListener("click", () => { this.downloadList() })
|
||||
}
|
||||
this.btnShuffle = document.getElementById("btn_shuffle");
|
||||
this.btnShuffle.style.display = "";
|
||||
this.btnShuffle.addEventListener("click", () => { this.toggleShuffle(); });
|
||||
this.btnShuffle = document.getElementById("btn_shuffle")
|
||||
this.btnShuffle.style.display = ""
|
||||
this.btnShuffle.addEventListener("click", () => { this.toggleShuffle() })
|
||||
|
||||
// Render list contents in list navigator div
|
||||
files.forEach((item, i) => {
|
||||
let filename;
|
||||
let filename
|
||||
if(item.name !== "null"){
|
||||
filename = item.name;
|
||||
filename = item.name
|
||||
}else{
|
||||
filename = "Removed File";
|
||||
filename = "Removed File"
|
||||
}
|
||||
|
||||
let d = document.createElement("div");
|
||||
d.classList = "file_button list_item";
|
||||
d.addEventListener("click", () => { this.setItem(i); });
|
||||
d.innerText = filename;
|
||||
this.divListNavigator.appendChild(d);
|
||||
});
|
||||
let d = document.createElement("div")
|
||||
d.classList = "file_button list_item"
|
||||
d.addEventListener("click", () => { this.setItem(i) })
|
||||
d.innerText = filename
|
||||
this.divListNavigator.appendChild(d)
|
||||
})
|
||||
|
||||
// Make the navigator visible
|
||||
this.divListNavigator.style.display = "inline-block";
|
||||
this.divListNavigator.style.display = "inline-block"
|
||||
|
||||
// Skip to the file defined in the link hash
|
||||
let matches = location.hash.match(new RegExp('item=([^&]*)'));
|
||||
let hashID = matches ? matches[1] : null;
|
||||
let matches = location.hash.match(new RegExp('item=([^&]*)'))
|
||||
let hashID = matches ? matches[1] : null
|
||||
|
||||
if(Number.isInteger(parseInt(hashID))){
|
||||
this.setItem(parseInt(hashID));
|
||||
this.setItem(parseInt(hashID))
|
||||
}else{
|
||||
this.setItem(0);
|
||||
this.setItem(0)
|
||||
}
|
||||
}
|
||||
|
||||
ListNavigator.prototype.nextItem = function() {
|
||||
if(this.shuffle){
|
||||
this.randItem();
|
||||
return;
|
||||
this.randItem()
|
||||
return
|
||||
}
|
||||
|
||||
if (this.position >= this.length) {
|
||||
this.position = 0;
|
||||
this.position = 0
|
||||
} else {
|
||||
this.position++;
|
||||
this.position++
|
||||
}
|
||||
|
||||
this.setItem(this.position);
|
||||
this.setItem(this.position)
|
||||
}
|
||||
|
||||
ListNavigator.prototype.previousItem = function() {
|
||||
if(this.position === 0){
|
||||
this.position = this.length - 1;
|
||||
this.position = this.length - 1
|
||||
}else{
|
||||
this.position--;
|
||||
this.position--
|
||||
}
|
||||
|
||||
this.setItem(this.position);
|
||||
this.setItem(this.position)
|
||||
}
|
||||
|
||||
ListNavigator.prototype.randItem = function() {
|
||||
// Avoid viewing the same file multiple times
|
||||
let rand;
|
||||
let rand
|
||||
do {
|
||||
rand = Math.round(Math.random() * this.length);
|
||||
console.log("rand is " + rand);
|
||||
} while(this.history.indexOf(rand) > -1);
|
||||
rand = Math.round(Math.random() * this.length)
|
||||
console.log("rand is " + rand)
|
||||
} while(this.history.indexOf(rand) > -1)
|
||||
|
||||
this.setItem(rand);
|
||||
this.setItem(rand)
|
||||
}
|
||||
|
||||
ListNavigator.prototype.setItem = function(index) {
|
||||
if(index >= this.length){
|
||||
this.position = 0;
|
||||
this.position = 0
|
||||
}else{
|
||||
this.position = index;
|
||||
this.position = index
|
||||
}
|
||||
|
||||
// Set the URL hash
|
||||
location.hash = "item=" + this.position;
|
||||
this.viewer.setFile(this.files[this.position]);
|
||||
location.hash = "item=" + this.position
|
||||
this.viewer.setFile(this.files[this.position])
|
||||
|
||||
this.addToHistory(index);
|
||||
this.loadThumbnails(index);
|
||||
this.addToHistory(index)
|
||||
this.loadThumbnails(index)
|
||||
|
||||
document.querySelectorAll("#list_navigator > .file_button_selected").forEach(el => {
|
||||
el.classList.remove("file_button_selected");
|
||||
});
|
||||
el.classList.remove("file_button_selected")
|
||||
})
|
||||
|
||||
let selectedItem = this.divListNavigator.children[this.position];
|
||||
selectedItem.classList.add("file_button_selected");
|
||||
let selectedItem = this.divListNavigator.children[this.position]
|
||||
selectedItem.classList.add("file_button_selected")
|
||||
|
||||
let cst = window.getComputedStyle(selectedItem);
|
||||
let itemWidth = selectedItem.offsetWidth + parseInt(cst.marginLeft) + parseInt(cst.marginRight);
|
||||
let cst = window.getComputedStyle(selectedItem)
|
||||
let itemWidth = selectedItem.offsetWidth + parseInt(cst.marginLeft) + parseInt(cst.marginRight)
|
||||
|
||||
let start = this.divListNavigator.scrollLeft;
|
||||
let end = ((this.position * itemWidth) + (itemWidth / 2)) - (this.divListNavigator.clientWidth / 2);
|
||||
let steps = 60; // One second
|
||||
let stepSize = (end - start)/steps;
|
||||
let start = this.divListNavigator.scrollLeft
|
||||
let end = ((this.position * itemWidth) + (itemWidth / 2)) - (this.divListNavigator.clientWidth / 2)
|
||||
let steps = 60 // One second
|
||||
let stepSize = (end - start)/steps
|
||||
|
||||
let animateScroll = (pos, step) => {
|
||||
this.divListNavigator.scrollLeft = pos;
|
||||
this.divListNavigator.scrollLeft = pos
|
||||
|
||||
if (step < steps) {
|
||||
requestAnimationFrame(() => {
|
||||
animateScroll(pos+stepSize, step+1);
|
||||
});
|
||||
animateScroll(pos+stepSize, step+1)
|
||||
})
|
||||
}
|
||||
};
|
||||
animateScroll(start, 0);
|
||||
}
|
||||
animateScroll(start, 0)
|
||||
}
|
||||
|
||||
ListNavigator.prototype.downloadList = function() {
|
||||
document.getElementById("download_frame").src = "/api/list/" + this.viewer.listId + "/zip";
|
||||
document.getElementById("download_frame").src = "/api/list/" + this.viewer.listId + "/zip"
|
||||
}
|
||||
|
||||
ListNavigator.prototype.addToHistory = function(index) {
|
||||
if(this.history.length >= (this.length - 6)){
|
||||
this.history.shift();
|
||||
this.history.shift()
|
||||
}
|
||||
this.history.push(index);
|
||||
this.history.push(index)
|
||||
}
|
||||
|
||||
ListNavigator.prototype.toggleShuffle = function() {
|
||||
this.shuffle = !this.shuffle; // :P
|
||||
this.shuffle = !this.shuffle // :P
|
||||
|
||||
if(this.shuffle){
|
||||
document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☑"; // Check icon
|
||||
this.btnShuffle.classList.add("button_highlight");
|
||||
document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☑" // Check icon
|
||||
this.btnShuffle.classList.add("button_highlight")
|
||||
}else{
|
||||
document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☐"; // Empty checkbox
|
||||
this.btnShuffle.classList.remove("button_highlight");
|
||||
document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☐" // Empty checkbox
|
||||
this.btnShuffle.classList.remove("button_highlight")
|
||||
}
|
||||
}
|
||||
|
||||
ListNavigator.prototype.loadThumbnails = function(index) {
|
||||
let startPos = +index - 50;
|
||||
let endPos = +index + 50;
|
||||
let startPos = +index - 50
|
||||
let endPos = +index + 50
|
||||
// fyi, the + is to let javascript know it's actually a number instead of a string
|
||||
|
||||
if(startPos < 0){
|
||||
startPos = 0;
|
||||
startPos = 0
|
||||
}
|
||||
if(endPos >= this.length){
|
||||
endPos = this.length - 1;
|
||||
endPos = this.length - 1
|
||||
}
|
||||
|
||||
let navigatorItems = document.getElementById("list_navigator").children
|
||||
|
||||
for (let i = startPos; i <= endPos; i++){
|
||||
if (navigatorItems[i].innerHTML.includes("list_item_thumbnail")) {
|
||||
continue; // Thumbnail already loaded
|
||||
continue // Thumbnail already loaded
|
||||
}
|
||||
|
||||
let thumb = "/api/file/" + this.files[i].id + "/thumbnail?width=48&height=48";
|
||||
let name = this.files[i].name;
|
||||
let thumb = "/api/file/" + this.files[i].id + "/thumbnail?width=48&height=48"
|
||||
let name = this.files[i].name
|
||||
|
||||
let itemHtml = "<img src=\"" + thumb + "\" "
|
||||
+ "class=\"list_item_thumbnail\" alt=\"" + escapeHTML(name) + "\"/>"
|
||||
+ escapeHTML(name);
|
||||
+ escapeHTML(name)
|
||||
|
||||
navigatorItems[i].innerHTML = itemHtml;
|
||||
navigatorItems[i].innerHTML = itemHtml
|
||||
}
|
||||
}
|
||||
|
@@ -1,41 +1,49 @@
|
||||
function Toolbar(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.visible = false;
|
||||
this.sharebarVisible = false;
|
||||
this.viewer = viewer
|
||||
this.visible = false
|
||||
this.sharebarVisible = false
|
||||
this.currentFile = null
|
||||
|
||||
this.divToolbar = document.getElementById("toolbar");
|
||||
this.divFilePreview = document.getElementById("filepreview");
|
||||
this.downloadFrame = document.getElementById("download_frame");
|
||||
this.spanViews = document.getElementById("stat_views");
|
||||
this.spanDownloads = document.getElementById("stat_downloads");
|
||||
this.spanSize = document.getElementById("stat_size");
|
||||
this.divToolbar = document.getElementById("toolbar")
|
||||
this.divFilePreview = document.getElementById("filepreview")
|
||||
this.downloadFrame = document.getElementById("download_frame")
|
||||
this.spanViews = document.getElementById("stat_views")
|
||||
this.spanDownloads = document.getElementById("stat_downloads")
|
||||
this.spanSize = document.getElementById("stat_size")
|
||||
|
||||
this.btnToggleToolbar = document.getElementById("btn_toggle_toolbar");
|
||||
this.btnDownload = document.getElementById("btn_download");
|
||||
this.btnCopyLink = document.getElementById("btn_copy");
|
||||
this.spanCopyLink = document.querySelector("#btn_copy > span");
|
||||
this.btnShare = document.getElementById("btn_share");
|
||||
this.divSharebar = document.getElementById("sharebar");
|
||||
this.btnToggleToolbar = document.getElementById("btn_toggle_toolbar")
|
||||
this.btnDownload = document.getElementById("btn_download")
|
||||
this.btnCopyLink = document.getElementById("btn_copy")
|
||||
this.spanCopyLink = document.querySelector("#btn_copy > span")
|
||||
this.btnShare = document.getElementById("btn_share")
|
||||
this.divSharebar = document.getElementById("sharebar")
|
||||
|
||||
this.btnToggleToolbar.addEventListener("click", () => { this.toggle(); });
|
||||
this.btnDownload.addEventListener("click", () => { this.download(); });
|
||||
this.btnCopyLink.addEventListener("click", () => { this.copyUrl(); });
|
||||
this.btnShare.addEventListener("click", () => { this.toggleSharebar(); });
|
||||
this.btnToggleToolbar.addEventListener("click", () => { this.toggle() })
|
||||
this.btnDownload.addEventListener("click", () => { this.download() })
|
||||
this.btnCopyLink.addEventListener("click", () => { this.copyUrl() })
|
||||
this.btnShare.addEventListener("click", () => { this.toggleSharebar() })
|
||||
}
|
||||
|
||||
Toolbar.prototype.setFile = function(file) {
|
||||
this.currentFile = file
|
||||
this.spanViews.innerText = file.views
|
||||
this.spanDownloads.innerText = Math.round((file.bandwidth_used/file.size)*10)/10
|
||||
this.spanSize.innerText = formatDataVolume(file.size, 3)
|
||||
}
|
||||
|
||||
Toolbar.prototype.toggle = function() {
|
||||
if (this.visible) {
|
||||
if (this.sharebarVisible) { this.toggleSharebar(); }
|
||||
if (this.sharebarVisible) { this.toggleSharebar() }
|
||||
|
||||
this.divToolbar.style.left = "-8em";
|
||||
this.divFilePreview.style.left = "0px";
|
||||
this.btnToggleToolbar.classList.remove("button_highlight");
|
||||
this.visible = false;
|
||||
this.divToolbar.style.left = "-8em"
|
||||
this.divFilePreview.style.left = "0px"
|
||||
this.btnToggleToolbar.classList.remove("button_highlight")
|
||||
this.visible = false
|
||||
} else {
|
||||
this.divToolbar.style.left = "0px";
|
||||
this.divFilePreview.style.left = "8em";
|
||||
this.btnToggleToolbar.classList.add("button_highlight");
|
||||
this.visible = true;
|
||||
this.divToolbar.style.left = "0px"
|
||||
this.divFilePreview.style.left = "8em"
|
||||
this.btnToggleToolbar.classList.add("button_highlight")
|
||||
this.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,132 +53,124 @@ Toolbar.prototype.toggleSharebar = function() {
|
||||
title: this.viewer.title,
|
||||
text: "Download " + this.viewer.title + " here",
|
||||
url: window.location.href
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if(this.sharebarVisible){
|
||||
this.divSharebar.style.left = "-8em";
|
||||
this.divSharebar.style.left = "-8em"
|
||||
this.btnShare.classList.remove("button_highlight")
|
||||
this.sharebarVisible = false;
|
||||
this.sharebarVisible = false
|
||||
}else{
|
||||
this.divSharebar.style.left = "8em";
|
||||
this.divSharebar.style.left = "8em"
|
||||
this.btnShare.classList.add("button_highlight")
|
||||
this.sharebarVisible = true;
|
||||
this.sharebarVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
Toolbar.prototype.download = function() {
|
||||
let triggerDL = (captchaResp = "") => {
|
||||
if (captchaResp === "") {
|
||||
this.downloadFrame.src = apiEndpoint+"/file/"+
|
||||
this.viewer.currentFile+"?download";
|
||||
this.downloadFrame.src = this.currentFile.download_href
|
||||
} else {
|
||||
this.downloadFrame.src = apiEndpoint+"/file/"+
|
||||
this.viewer.currentFile+"?download&recaptcha_response="+captchaResp;
|
||||
this.downloadFrame.src = this.currentFile.download_href+"&recaptcha_response="+captchaResp
|
||||
}
|
||||
}
|
||||
|
||||
if (captchaKey === "none"){
|
||||
if (captchaKey === "none" || captchaKey === ""){
|
||||
// If the server doesn't support captcha there's no use in checking
|
||||
// availability
|
||||
triggerDL();
|
||||
return;
|
||||
triggerDL()
|
||||
return
|
||||
}
|
||||
if (recaptchaResponse !== "") {
|
||||
// Captcha already filled in. Use the saved captcha responsse to
|
||||
// download the file
|
||||
triggerDL(recaptchaResponse);
|
||||
triggerDL(recaptchaResponse)
|
||||
|
||||
// Reset the key
|
||||
recaptchaResponse = "";
|
||||
return;
|
||||
recaptchaResponse = ""
|
||||
return
|
||||
}
|
||||
|
||||
fetch(apiEndpoint+"/file/"+this.viewer.currentFile+"/availability").then(resp => {
|
||||
return resp.json();
|
||||
fetch(this.currentFile.file_availability_href).then(resp => {
|
||||
return resp.json()
|
||||
}).then(resp => {
|
||||
let popupDiv = document.getElementById("captcha_popup");
|
||||
let popupTitle = document.getElementById("captcha_popup_title");
|
||||
let popupContent = document.getElementById("captcha_popup_content");
|
||||
let popupDiv = document.getElementById("captcha_popup")
|
||||
let popupTitle = document.getElementById("captcha_popup_title")
|
||||
let popupContent = document.getElementById("captcha_popup_content")
|
||||
|
||||
let showCaptcha = () => {
|
||||
// Load the recaptcha script with a load function
|
||||
let script = document.createElement("script");
|
||||
script.src = "https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit";
|
||||
document.body.appendChild(script);
|
||||
let script = document.createElement("script")
|
||||
script.src = "https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit"
|
||||
document.body.appendChild(script)
|
||||
|
||||
// Show the popup
|
||||
popupDiv.style.opacity = "1";
|
||||
popupDiv.style.visibility = "visible";
|
||||
popupDiv.style.opacity = "1"
|
||||
popupDiv.style.visibility = "visible"
|
||||
}
|
||||
|
||||
if (resp.value === "file_rate_limited_captcha_required") {
|
||||
popupTitle.innerText = "Rate limiting enabled!";
|
||||
popupTitle.innerText = "Rate limiting enabled!"
|
||||
popupContent.innerText = "This file is using a suspicious "+
|
||||
"amount of bandwidth relative to its popularity. To "+
|
||||
"continue downloading this file you will have to "+
|
||||
"prove that you're a human first.";
|
||||
showCaptcha();
|
||||
"prove that you're a human first."
|
||||
showCaptcha()
|
||||
} else if (resp.value === "virus_detected_captcha_required") {
|
||||
popupTitle.innerText = "Malware warning!";
|
||||
popupTitle.innerText = "Malware warning!"
|
||||
popupContent.innerText = "According to our scanning "+
|
||||
"systems this file may contain a virus of type '"+
|
||||
resp.extra+"'. You can continue downloading this file at "+
|
||||
"your own risk, but you will have to prove that you're a "+
|
||||
"human first.";
|
||||
showCaptcha();
|
||||
"human first."
|
||||
showCaptcha()
|
||||
} else {
|
||||
console.warn("resp.value not valid: "+resp.value);
|
||||
triggerDL();
|
||||
console.warn("resp.value not valid: "+resp.value)
|
||||
triggerDL()
|
||||
}
|
||||
}).catch(e => {
|
||||
console.warn("fetch availability failed: "+e);
|
||||
triggerDL();
|
||||
});
|
||||
console.warn("fetch availability failed: "+e)
|
||||
triggerDL()
|
||||
})
|
||||
}
|
||||
|
||||
Toolbar.prototype.copyUrl = function() {
|
||||
if(copyText(window.location.href)) {
|
||||
console.log('Text copied');
|
||||
this.spanCopyLink.innerText = "Copied!";
|
||||
console.log('Text copied')
|
||||
this.spanCopyLink.innerText = "Copied!"
|
||||
this.btnCopyLink.classList.add("button_highlight")
|
||||
} else {
|
||||
console.log('Copying not supported');
|
||||
this.spanCopyLink.innerText = "Error!";
|
||||
alert("Your browser does not support copying text.");
|
||||
console.log('Copying not supported')
|
||||
this.spanCopyLink.innerText = "Error!"
|
||||
alert("Your browser does not support copying text.")
|
||||
}
|
||||
|
||||
// Return to normal
|
||||
setTimeout(() => {
|
||||
this.spanCopyLink.innerText = "Copy";
|
||||
this.spanCopyLink.innerText = "Copy"
|
||||
this.btnCopyLink.classList.remove("button_highlight")
|
||||
}, 60000);
|
||||
}
|
||||
|
||||
Toolbar.prototype.setStats = function(file) {
|
||||
this.spanViews.innerText = file.views
|
||||
this.spanDownloads.innerText = Math.round((file.bandwidth_used/file.size)*10)/10;
|
||||
this.spanSize.innerText = formatDataVolume(file.size, 3);
|
||||
}, 60000)
|
||||
}
|
||||
|
||||
|
||||
// Called by the google recaptcha script
|
||||
let recaptchaResponse = "";
|
||||
let recaptchaResponse = ""
|
||||
function loadCaptcha(){
|
||||
grecaptcha.render("captcha_popup_captcha", {
|
||||
sitekey: captchaKey,
|
||||
theme: "dark",
|
||||
callback: token => {
|
||||
recaptchaResponse = token;
|
||||
document.getElementById("btn_download").click();
|
||||
recaptchaResponse = token
|
||||
document.getElementById("btn_download").click()
|
||||
|
||||
// Hide the popup
|
||||
setTimeout(() => {
|
||||
let popupDiv = document.getElementById("captcha_popup");
|
||||
popupDiv.style.opacity = "0";
|
||||
popupDiv.style.visibility = "hidden";
|
||||
let popupDiv = document.getElementById("captcha_popup")
|
||||
popupDiv.style.opacity = "0"
|
||||
popupDiv.style.visibility = "hidden"
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
@@ -1,27 +1,26 @@
|
||||
function Viewer(type, viewToken, data) {
|
||||
// Set defaults
|
||||
this.toolbar = null;
|
||||
this.listNavigator = null;
|
||||
this.detailsWindow = null;
|
||||
this.divFilepreview = null;
|
||||
this.currentFile = "";
|
||||
this.title = ""; // Contains either the file name or list title
|
||||
this.listId = "";
|
||||
this.viewToken = "";
|
||||
this.isList = false;
|
||||
this.isFile = false;
|
||||
this.initialized = false;
|
||||
this.toolbar = null
|
||||
this.listNavigator = null
|
||||
this.detailsWindow = null
|
||||
this.divFilepreview = null
|
||||
this.title = "" // Contains either the file name or list title
|
||||
this.listId = ""
|
||||
this.viewToken = ""
|
||||
this.isList = false
|
||||
this.isFile = false
|
||||
this.initialized = false
|
||||
|
||||
this.viewToken = viewToken;
|
||||
this.toolbar = new Toolbar(this);
|
||||
this.detailsWindow = new DetailsWindow(this);
|
||||
this.viewToken = viewToken
|
||||
this.toolbar = new Toolbar(this)
|
||||
this.detailsWindow = new DetailsWindow(this)
|
||||
|
||||
this.divFilepreview = document.getElementById("filepreview");
|
||||
this.divFilepreview = document.getElementById("filepreview")
|
||||
|
||||
// On small screens the toolbar takes too much space, so it collapses
|
||||
// automatically
|
||||
if (this.divFilepreview.clientWidth > 600 && !this.toolbar.visible) {
|
||||
this.toolbar.toggle();
|
||||
this.toolbar.toggle()
|
||||
}
|
||||
|
||||
// The close button only works if the window has an opener. So we hide
|
||||
@@ -31,106 +30,122 @@ function Viewer(type, viewToken, data) {
|
||||
}
|
||||
|
||||
if (type === "file") {
|
||||
this.isFile = true;
|
||||
this.currentFile = data.id;
|
||||
this.title = data.name;
|
||||
this.setFile(data);
|
||||
this.isFile = true
|
||||
this.title = data.name
|
||||
this.setFile(fileFromAPIResp(data))
|
||||
} else if (type === "list") {
|
||||
this.isList = true;
|
||||
this.listId = data.id;
|
||||
this.title = data.title;
|
||||
this.listNavigator = new ListNavigator(this, data.files);
|
||||
this.isList = true
|
||||
this.listId = data.id
|
||||
this.title = data.title
|
||||
|
||||
let files = []
|
||||
for (let i in data.files) {
|
||||
files.push(fileFromAPIResp(data.files[i]))
|
||||
}
|
||||
this.listNavigator = new ListNavigator(this, files)
|
||||
} else if (type === "skylink") {
|
||||
this.isFile = true
|
||||
this.title = data.name
|
||||
document.getElementById("btn_details").remove()
|
||||
document.getElementById("stat_views_label").remove()
|
||||
document.getElementById("stat_views").remove()
|
||||
document.getElementById("stat_downloads_label").remove()
|
||||
document.getElementById("stat_downloads").remove()
|
||||
|
||||
let file = fileFromSkyNet(data)
|
||||
console.log(file)
|
||||
this.setFile(file)
|
||||
}
|
||||
|
||||
this.renderSponsors();
|
||||
window.addEventListener("resize", e => { this.renderSponsors(e); });
|
||||
this.renderSponsors()
|
||||
window.addEventListener("resize", e => { this.renderSponsors(e) })
|
||||
|
||||
// Register keyboard shortcuts
|
||||
document.addEventListener("keydown", e => { this.keyboardEvent(e); });
|
||||
document.addEventListener("keydown", e => { this.keyboardEvent(e) })
|
||||
|
||||
this.initialized = true;
|
||||
this.initialized = true
|
||||
}
|
||||
|
||||
Viewer.prototype.setFile = function(file) {
|
||||
this.currentFile = file.id;
|
||||
if (this.isList) {
|
||||
document.getElementById("file_viewer_headerbar_title").style.lineHeight = "1em";
|
||||
document.getElementById("file_viewer_list_title").innerText = this.title;
|
||||
document.getElementById("file_viewer_file_title").innerText = file.name;
|
||||
document.title = this.title + " ~ " + file.name + " ~ pixeldrain";
|
||||
document.getElementById("file_viewer_headerbar_title").style.lineHeight = "1em"
|
||||
document.getElementById("file_viewer_list_title").innerText = this.title
|
||||
document.getElementById("file_viewer_file_title").innerText = file.name
|
||||
document.title = this.title + " ~ " + file.name + " ~ pixeldrain"
|
||||
} else {
|
||||
document.getElementById("file_viewer_file_title").innerText = file.name;
|
||||
document.title = file.name + " ~ pixeldrain";
|
||||
document.getElementById("file_viewer_file_title").innerText = file.name
|
||||
document.title = file.name + " ~ pixeldrain"
|
||||
}
|
||||
|
||||
// Update the file details
|
||||
this.detailsWindow.setDetails(file);
|
||||
this.toolbar.setStats(file);
|
||||
this.detailsWindow.setDetails(file)
|
||||
this.toolbar.setFile(file)
|
||||
|
||||
// Register a new view. We don't care what this returns becasue we can't
|
||||
// do anything about it anyway
|
||||
fetch(apiEndpoint+"/file/"+file.id+"/view",
|
||||
{
|
||||
if (file.view_href !== "") {
|
||||
fetch(file.view_href, {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/x-www-form-urlencoded"},
|
||||
body: "token="+this.viewToken
|
||||
}
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
// Clear the canvas
|
||||
this.divFilepreview.innerHTML = "";
|
||||
this.divFilepreview.innerHTML = ""
|
||||
|
||||
let nextItem = () => {
|
||||
if (this.listNavigator !== null) {
|
||||
this.listNavigator.nextItem();
|
||||
this.listNavigator.nextItem()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (
|
||||
file.mime_type.startsWith("image")
|
||||
) {
|
||||
new ImageViewer(this, file).render(this.divFilepreview);
|
||||
new ImageViewer(this, file).render(this.divFilepreview)
|
||||
} else if (
|
||||
file.mime_type.startsWith("video") ||
|
||||
file.mime_type === "application/matroska" ||
|
||||
file.mime_type === "application/x-matroska"
|
||||
) {
|
||||
new VideoViewer(this, file, nextItem).render(this.divFilepreview);
|
||||
new VideoViewer(this, file, nextItem).render(this.divFilepreview)
|
||||
} else if (
|
||||
file.mime_type.startsWith("audio") ||
|
||||
file.mime_type === "application/ogg" ||
|
||||
file.name.endsWith(".mp3")
|
||||
) {
|
||||
new AudioViewer(this, file, nextItem).render(this.divFilepreview);
|
||||
new AudioViewer(this, file, nextItem).render(this.divFilepreview)
|
||||
} else if (
|
||||
file.mime_type === "application/pdf" ||
|
||||
file.mime_type === "application/x-pdf"
|
||||
) {
|
||||
new PDFViewer(this, file).render(this.divFilepreview);
|
||||
new PDFViewer(this, file).render(this.divFilepreview)
|
||||
} else if (
|
||||
file.mime_type.startsWith("text") ||
|
||||
file.id === "demo"
|
||||
) {
|
||||
new TextViewer(this, file).render(this.divFilepreview);
|
||||
new TextViewer(this, file).render(this.divFilepreview)
|
||||
} else {
|
||||
new FileViewer(this, file).render(this.divFilepreview);
|
||||
new FileViewer(this, file).render(this.divFilepreview)
|
||||
}
|
||||
}
|
||||
|
||||
Viewer.prototype.renderSponsors = function() {
|
||||
let scale = 1;
|
||||
let scaleWidth = 1;
|
||||
let scaleHeight = 1;
|
||||
let minWidth = 728;
|
||||
let minHeight = 800;
|
||||
let scale = 1
|
||||
let scaleWidth = 1
|
||||
let scaleHeight = 1
|
||||
let minWidth = 728
|
||||
let minHeight = 800
|
||||
|
||||
if (window.innerWidth < minWidth) {
|
||||
scaleWidth = window.innerWidth/minWidth;
|
||||
scaleWidth = window.innerWidth/minWidth
|
||||
}
|
||||
if (window.innerHeight < minHeight) {
|
||||
scaleHeight = window.innerHeight/minHeight;
|
||||
scaleHeight = window.innerHeight/minHeight
|
||||
}
|
||||
scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
|
||||
scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight
|
||||
|
||||
// Because of the scale transformation the automatic margins don't work
|
||||
// anymore. So we have to maunally calculate the margin. Where we take the
|
||||
@@ -141,14 +156,14 @@ Viewer.prototype.renderSponsors = function() {
|
||||
if (offset < 0) {
|
||||
offset = 0
|
||||
}
|
||||
document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px";
|
||||
document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px"
|
||||
|
||||
if (scale == 1) {
|
||||
document.querySelector(".sponsors > iframe").style.transform = "none";
|
||||
document.querySelector(".sponsors").style.height = "90px";
|
||||
document.querySelector(".sponsors > iframe").style.transform = "none"
|
||||
document.querySelector(".sponsors").style.height = "90px"
|
||||
} else {
|
||||
document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")";
|
||||
document.querySelector(".sponsors").style.height = (scale*90)+"px";
|
||||
document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")"
|
||||
document.querySelector(".sponsors").style.height = (scale*90)+"px"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,36 +176,36 @@ Viewer.prototype.keyboardEvent = function(evt) {
|
||||
case 65: // A or left arrow key go to previous file
|
||||
case 37:
|
||||
if (this.listNavigator != null) {
|
||||
this.listNavigator.previousItem();
|
||||
this.listNavigator.previousItem()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 68: // D or right arrow key go to next file
|
||||
case 39:
|
||||
if (this.listNavigator != null) {
|
||||
this.listNavigator.nextItem();
|
||||
this.listNavigator.nextItem()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 83:
|
||||
if (evt.shiftKey) {
|
||||
this.listNavigator.downloadList(); // SHIFT + S downloads all files in list
|
||||
this.listNavigator.downloadList() // SHIFT + S downloads all files in list
|
||||
} else {
|
||||
this.toolbar.download(); // S to download the current file
|
||||
this.toolbar.download() // S to download the current file
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 82: // R to toggle list shuffle
|
||||
if (this.listNavigator != null) {
|
||||
this.listNavigator.toggleShuffle();
|
||||
this.listNavigator.toggleShuffle()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 67: // C to copy to clipboard
|
||||
this.toolbar.copyUrl();
|
||||
break;
|
||||
this.toolbar.copyUrl()
|
||||
break
|
||||
case 73: // I to open the details window
|
||||
this.detailsWindow.toggle();
|
||||
break;
|
||||
this.detailsWindow.toggle()
|
||||
break
|
||||
case 81: // Q to close the window
|
||||
window.close();
|
||||
break;
|
||||
window.close()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,3 +218,39 @@ function escapeHTML(str) {
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
}
|
||||
|
||||
function fileFromAPIResp(resp) {
|
||||
let file = {
|
||||
id: resp.id,
|
||||
name: resp.name,
|
||||
mime_type: resp.mime_type,
|
||||
size: resp.size,
|
||||
date_created: new Date(resp.date_upload),
|
||||
date_last_view: new Date(resp.date_last_view),
|
||||
views: resp.views,
|
||||
bandwidth_used: resp.bandwidth_used,
|
||||
description: "",
|
||||
icon_href: apiEndpoint+"/file/"+resp.id+"/thumbnail",
|
||||
get_href: apiEndpoint+"/file/"+resp.id,
|
||||
download_href: apiEndpoint+"/file/"+resp.id+"?download",
|
||||
availability_href: apiEndpoint+"/file/"+resp.id+"/availability",
|
||||
view_href: apiEndpoint+"/file/"+resp.id+"/view",
|
||||
timeseries_href: apiEndpoint+"/file/"+resp.id+"/timeseries",
|
||||
link: domainURL()+"/u/"+resp.id,
|
||||
}
|
||||
if (resp.description !== undefined) {
|
||||
file.description = resp.description
|
||||
}
|
||||
return file
|
||||
}
|
||||
function fileFromSkyNet(resp) {
|
||||
let file = fileFromAPIResp(resp)
|
||||
file.icon_href = "/res/img/mime/empty.png"
|
||||
file.get_href = "https://siasky.net/"+resp.id
|
||||
file.download_href = "https://siasky.net/"+resp.id
|
||||
file.availability_href = ""
|
||||
file.view_href = ""
|
||||
file.timeseries_href = ""
|
||||
file.link = domainURL()+"/s/"+resp.id
|
||||
return file
|
||||
}
|
||||
|
@@ -1,33 +1,33 @@
|
||||
function AudioViewer(viewer, file, next) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.next = next;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
this.next = next
|
||||
|
||||
this.container = document.createElement("div");
|
||||
this.container.classList = "image-container";
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container = document.createElement("div")
|
||||
this.container.classList = "image-container"
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
|
||||
this.icon = document.createElement("img");
|
||||
this.icon.src = "/res/img/mime/audio.png";
|
||||
this.container.appendChild(this.icon);
|
||||
this.icon = document.createElement("img")
|
||||
this.icon.src = "/res/img/mime/audio.png"
|
||||
this.container.appendChild(this.icon)
|
||||
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createTextNode(file.name));
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createTextNode(this.file.name))
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
|
||||
this.element = document.createElement("audio");
|
||||
this.element.autoplay = "autoplay";
|
||||
this.element.controls = "controls";
|
||||
this.element.style.width = "90%";
|
||||
this.element.addEventListener("ended", () => { this.next(); }, false);
|
||||
this.element = document.createElement("audio")
|
||||
this.element.autoplay = "autoplay"
|
||||
this.element.controls = "controls"
|
||||
this.element.style.width = "90%"
|
||||
this.element.addEventListener("ended", () => { this.next() }, false)
|
||||
|
||||
this.source = document.createElement("source");
|
||||
this.source.src = apiEndpoint+"/file/"+this.file.id;
|
||||
this.element.appendChild(this.source);
|
||||
this.container.appendChild(this.element);
|
||||
this.source = document.createElement("source")
|
||||
this.source.src = this.file.get_href
|
||||
this.element.appendChild(this.source)
|
||||
this.container.appendChild(this.element)
|
||||
}
|
||||
|
||||
AudioViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.container);
|
||||
parent.appendChild(this.container)
|
||||
}
|
||||
|
@@ -1,27 +1,27 @@
|
||||
function FileViewer(viewer, file, next) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.next = next;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
this.next = next
|
||||
|
||||
this.container = document.createElement("div");
|
||||
this.container.classList = "image-container";
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container = document.createElement("div")
|
||||
this.container.classList = "image-container"
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
|
||||
this.icon = document.createElement("img");
|
||||
this.icon.src = apiEndpoint+"/"+file.thumbnail_href;
|
||||
this.container.appendChild(this.icon);
|
||||
this.icon = document.createElement("img")
|
||||
this.icon.src = this.file.icon_href
|
||||
this.container.appendChild(this.icon)
|
||||
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createTextNode(file.name));
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createTextNode("Type: "+file.mime_type));
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createElement("br"));
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createTextNode(file.name))
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createTextNode("Type: "+file.mime_type))
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createElement("br"))
|
||||
this.container.appendChild(document.createTextNode(
|
||||
"Press the 'Download' button in the menu to download this file"
|
||||
));
|
||||
))
|
||||
}
|
||||
|
||||
FileViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.container);
|
||||
parent.appendChild(this.container)
|
||||
}
|
||||
|
@@ -1,88 +1,86 @@
|
||||
function ImageViewer(viewer, file) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.zoomed = false;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.dragging = false;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
this.zoomed = false
|
||||
this.x = 0
|
||||
this.y = 0
|
||||
this.dragging = false
|
||||
|
||||
this.container = document.createElement("dv");
|
||||
this.container.classList = "image-container";
|
||||
// this.container.style.lineHeight = "0";
|
||||
this.container = document.createElement("dv")
|
||||
this.container.classList = "image-container"
|
||||
|
||||
this.element = document.createElement("img");
|
||||
this.element.classList = "pannable center drop-shadow";
|
||||
this.element.src = apiEndpoint+"/file/"+this.file.id;
|
||||
this.element.addEventListener("dblclick", (e) => { return this.doubleclick(e); });
|
||||
this.element.addEventListener("doubletap", (e) => { return this.doubleclick(e); });
|
||||
this.element.addEventListener("mousedown", (e) => { return this.mousedown(e); });
|
||||
document.addEventListener("mousemove", (e) => { return this.mousemove(e); });
|
||||
document.addEventListener("mouseup", (e) => { return this.mouseup(e); });
|
||||
this.element = document.createElement("img")
|
||||
this.element.classList = "pannable center drop-shadow"
|
||||
this.element.src = this.file.get_href
|
||||
this.element.addEventListener("dblclick", (e) => { return this.doubleclick(e) })
|
||||
this.element.addEventListener("doubletap", (e) => { return this.doubleclick(e) })
|
||||
this.element.addEventListener("mousedown", (e) => { return this.mousedown(e) })
|
||||
document.addEventListener("mousemove", (e) => { return this.mousemove(e) })
|
||||
document.addEventListener("mouseup", (e) => { return this.mouseup(e) })
|
||||
|
||||
this.container.appendChild(this.element);
|
||||
this.container.appendChild(this.element)
|
||||
}
|
||||
|
||||
ImageViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.container);
|
||||
parent.appendChild(this.container)
|
||||
}
|
||||
|
||||
ImageViewer.prototype.doubleclick = function(e) {
|
||||
if (this.zoomed) {
|
||||
this.element.style.maxWidth = "100%";
|
||||
this.element.style.maxHeight = "100%";
|
||||
this.element.style.top = "50%";
|
||||
this.element.style.left = "auto";
|
||||
this.element.style.transform = "translateY(-50%)";
|
||||
this.container.style.overflow = "hidden";
|
||||
this.zoomed = false;
|
||||
this.element.style.maxWidth = "100%"
|
||||
this.element.style.maxHeight = "100%"
|
||||
this.element.style.top = "50%"
|
||||
this.element.style.left = "auto"
|
||||
this.element.style.transform = "translateY(-50%)"
|
||||
this.container.style.overflow = "hidden"
|
||||
this.zoomed = false
|
||||
} else {
|
||||
this.element.style.maxWidth = "none";
|
||||
this.element.style.maxHeight = "none";
|
||||
this.element.style.top = "0";
|
||||
this.element.style.left = "";
|
||||
this.element.style.transform = "none";
|
||||
this.container.style.overflow = "scroll";
|
||||
this.zoomed = true;
|
||||
this.element.style.maxWidth = "none"
|
||||
this.element.style.maxHeight = "none"
|
||||
this.element.style.top = "0"
|
||||
this.element.style.left = ""
|
||||
this.element.style.transform = "none"
|
||||
this.container.style.overflow = "scroll"
|
||||
this.zoomed = true
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
return false
|
||||
}
|
||||
|
||||
ImageViewer.prototype.mousedown = function(e) {
|
||||
if (!this.dragging && e.which === 1 && this.zoomed) {
|
||||
this.x = e.pageX;
|
||||
this.y = e.pageY;
|
||||
this.dragging = true;
|
||||
this.x = e.pageX
|
||||
this.y = e.pageY
|
||||
this.dragging = true
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ImageViewer.prototype.mousemove = function(e) {
|
||||
if (this.dragging) {
|
||||
this.container.scrollLeft = this.container.scrollLeft - (e.pageX - this.x);
|
||||
this.container.scrollTop = this.container.scrollTop - (e.pageY - this.y);
|
||||
this.container.scrollLeft = this.container.scrollLeft - (e.pageX - this.x)
|
||||
this.container.scrollTop = this.container.scrollTop - (e.pageY - this.y)
|
||||
|
||||
this.x = e.pageX;
|
||||
this.y = e.pageY;
|
||||
this.x = e.pageX
|
||||
this.y = e.pageY
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ImageViewer.prototype.mouseup = function(e) {
|
||||
if (this.dragging) {
|
||||
this.dragging = false;
|
||||
this.dragging = false
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,12 @@
|
||||
function PDFViewer(viewer, file) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
|
||||
this.container = document.createElement("iframe");
|
||||
this.container.classList = "image-container";
|
||||
this.container.style.border = "none";
|
||||
this.container.src = "/res/misc/pdf-viewer/web/viewer.html?file="+apiEndpoint+"/file/"+file.id;
|
||||
this.container = document.createElement("iframe")
|
||||
this.container.classList = "image-container"
|
||||
this.container.style.border = "none"
|
||||
this.container.src = "/res/misc/pdf-viewer/web/viewer.html?file="+this.file.get_href
|
||||
}
|
||||
|
||||
PDFViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.container);
|
||||
parent.appendChild(this.container)
|
||||
}
|
||||
|
@@ -1,56 +1,58 @@
|
||||
function TextViewer(viewer, file) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.pre = null;
|
||||
this.prettyprint = null;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
this.pre = null
|
||||
this.prettyprint = null
|
||||
|
||||
this.container = document.createElement("div");
|
||||
this.container.classList = "text-container";
|
||||
this.container = document.createElement("div")
|
||||
this.container.classList = "text-container"
|
||||
|
||||
if (file.name.endsWith(".md") || file.name.endsWith(".markdown") || file.id === "demo") {
|
||||
this.getMarkdown();
|
||||
if (this.file.name.endsWith(".md") || this.file.name.endsWith(".markdown") || file.mime_type === "text/demo") {
|
||||
this.getMarkdown()
|
||||
} else {
|
||||
this.getText();
|
||||
this.getText()
|
||||
}
|
||||
}
|
||||
|
||||
TextViewer.prototype.getText = function() {
|
||||
this.pre = document.createElement("pre");
|
||||
this.pre.classList = "pre-container prettyprint linenums";
|
||||
this.pre.innerText = "Loading...";
|
||||
this.container.appendChild(this.pre);
|
||||
this.pre = document.createElement("pre")
|
||||
this.pre.classList = "pre-container prettyprint linenums"
|
||||
this.pre.innerText = "Loading..."
|
||||
this.container.appendChild(this.pre)
|
||||
|
||||
if (this.file.size > 1<<20) { // File larger than 1 MiB
|
||||
this.pre.innerText = "File is too large to view online.\nPlease download and view it locally.";
|
||||
return;
|
||||
this.pre.innerText = "File is too large to view online.\nPlease download and view it locally."
|
||||
return
|
||||
}
|
||||
|
||||
fetch(apiEndpoint+"/file/"+this.file.id).then(resp => {
|
||||
if (!resp.ok) { return Promise.reject(resp.status); }
|
||||
return resp.text();
|
||||
fetch(this.file.get_href).then(resp => {
|
||||
if (!resp.ok) { return Promise.reject(resp.status) }
|
||||
return resp.text()
|
||||
}).then(resp => {
|
||||
this.pre.innerText = resp;
|
||||
this.pre.innerText = resp
|
||||
|
||||
// Load prettyprint script
|
||||
this.prettyprint = document.createElement("script");
|
||||
this.prettyprint.src = "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert";
|
||||
this.container.appendChild(this.prettyprint);
|
||||
this.prettyprint = document.createElement("script")
|
||||
this.prettyprint.src = "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"
|
||||
this.container.appendChild(this.prettyprint)
|
||||
}).catch(err => {
|
||||
this.pre.innerText = "Error loading file: "+err;
|
||||
});
|
||||
this.pre.innerText = "Error loading file: "+err
|
||||
})
|
||||
}
|
||||
|
||||
TextViewer.prototype.getMarkdown = function() {
|
||||
fetch("/u/"+this.file.id+"/preview").then(resp => {
|
||||
if (!resp.ok) { return Promise.reject(resp.status); }
|
||||
return resp.text();
|
||||
fetch(
|
||||
domainURL()+window.location.pathname+"/preview"
|
||||
).then(resp => {
|
||||
if (!resp.ok) { return Promise.reject(resp.status) }
|
||||
return resp.text()
|
||||
}).then(resp => {
|
||||
this.container.innerHTML = resp;
|
||||
this.container.innerHTML = resp
|
||||
}).catch(err => {
|
||||
this.container.innerText = "Error loading file: "+err;
|
||||
});
|
||||
this.container.innerText = "Error loading file: "+err
|
||||
})
|
||||
}
|
||||
|
||||
TextViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.container);
|
||||
parent.appendChild(this.container)
|
||||
}
|
||||
|
@@ -1,24 +1,24 @@
|
||||
function VideoViewer(viewer, file, next) {
|
||||
this.viewer = viewer;
|
||||
this.file = file;
|
||||
this.next = next;
|
||||
this.viewer = viewer
|
||||
this.file = file
|
||||
this.next = next
|
||||
|
||||
this.vidContainer = document.createElement("div");
|
||||
this.vidContainer.classList = "image-container";
|
||||
this.vidContainer = document.createElement("div")
|
||||
this.vidContainer.classList = "image-container"
|
||||
|
||||
this.vidElement = document.createElement("video");
|
||||
this.vidElement.autoplay = "autoplay";
|
||||
this.vidElement.controls = "controls";
|
||||
this.vidElement.classList = "center drop-shadow";
|
||||
this.vidElement.addEventListener("ended", () => { this.next(); }, false);
|
||||
this.vidElement = document.createElement("video")
|
||||
this.vidElement.autoplay = "autoplay"
|
||||
this.vidElement.controls = "controls"
|
||||
this.vidElement.classList = "center drop-shadow"
|
||||
this.vidElement.addEventListener("ended", () => { this.next() }, false)
|
||||
|
||||
this.videoSource = document.createElement("source");
|
||||
this.videoSource.src = apiEndpoint+"/file/"+this.file.id;
|
||||
this.videoSource = document.createElement("source")
|
||||
this.videoSource.src = this.file.get_href
|
||||
|
||||
this.vidElement.appendChild(this.videoSource);
|
||||
this.vidContainer.appendChild(this.vidElement);
|
||||
this.vidElement.appendChild(this.videoSource)
|
||||
this.vidContainer.appendChild(this.vidElement)
|
||||
}
|
||||
|
||||
VideoViewer.prototype.render = function(parent) {
|
||||
parent.appendChild(this.vidContainer);
|
||||
parent.appendChild(this.vidContainer)
|
||||
}
|
||||
|
@@ -1,78 +1,77 @@
|
||||
function renderFileButton(apiURL, id, title, subtitle) {
|
||||
let btn = document.createElement("a");
|
||||
btn.classList = "file_button";
|
||||
btn.href = "/u/"+id;
|
||||
btn.target = "_blank";
|
||||
let thumbnail = document.createElement("img");
|
||||
thumbnail.src = apiURL+"/file/"+id+"/thumbnail?width=80&height=80";
|
||||
thumbnail.alt = title;
|
||||
let titleSpan = document.createElement("span");
|
||||
titleSpan.classList = "file_button_title";
|
||||
titleSpan.innerText = title;
|
||||
let br = document.createElement("br");
|
||||
let subtitleSpan = document.createElement("span");
|
||||
subtitleSpan.classList = "file_button_subtitle";
|
||||
subtitleSpan.innerText = subtitle;
|
||||
let btn = document.createElement("a")
|
||||
btn.classList = "file_button"
|
||||
btn.href = "/u/"+id
|
||||
btn.target = "_blank"
|
||||
let thumbnail = document.createElement("img")
|
||||
thumbnail.src = apiURL+"/file/"+id+"/thumbnail?width=80&height=80"
|
||||
thumbnail.alt = title
|
||||
let titleSpan = document.createElement("span")
|
||||
titleSpan.classList = "file_button_title"
|
||||
titleSpan.innerText = title
|
||||
let br = document.createElement("br")
|
||||
let subtitleSpan = document.createElement("span")
|
||||
subtitleSpan.classList = "file_button_subtitle"
|
||||
subtitleSpan.innerText = subtitle
|
||||
|
||||
btn.appendChild(thumbnail);
|
||||
btn.appendChild(titleSpan);
|
||||
btn.appendChild(br);
|
||||
btn.appendChild(subtitleSpan);
|
||||
return btn;
|
||||
btn.appendChild(thumbnail)
|
||||
btn.appendChild(titleSpan)
|
||||
btn.appendChild(br)
|
||||
btn.appendChild(subtitleSpan)
|
||||
return btn
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie);
|
||||
return result ? result[1] : null;
|
||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)
|
||||
return result ? result[1] : null
|
||||
}
|
||||
|
||||
// Get the uploads from localstorage
|
||||
let uploadsStr = localStorage.getItem("uploaded_files");
|
||||
if (uploadsStr === null) { uploadsStr = ""; }
|
||||
let uploadsStr = localStorage.getItem("uploaded_files")
|
||||
if (uploadsStr === null) { uploadsStr = "" }
|
||||
|
||||
let uploads = Array();
|
||||
let uploads = Array()
|
||||
|
||||
if (uploadsStr != "") {
|
||||
uploadsStr = uploadsStr.slice(0, -1); // Strip the trailing comma
|
||||
uploads = uploadsStr.split(",");
|
||||
uploadsStr = uploadsStr.slice(0, -1) // Strip the trailing comma
|
||||
uploads = uploadsStr.split(",")
|
||||
}
|
||||
|
||||
// Get the uploads from a cookie
|
||||
uploadsStr = getCookie("pduploads");
|
||||
if (uploadsStr === null) { uploadsStr = ""; }
|
||||
uploadsStr = getCookie("pduploads")
|
||||
if (uploadsStr === null) { uploadsStr = "" }
|
||||
|
||||
if (uploadsStr != "") {
|
||||
uploadsStr = uploadsStr.slice(0, -1); // Strip the trailing dot
|
||||
uploads.push(uploadsStr.split(".").reverse());
|
||||
uploadsStr = uploadsStr.slice(0, -1) // Strip the trailing dot
|
||||
uploads.push(uploadsStr.split(".").reverse())
|
||||
}
|
||||
|
||||
// Render all the items
|
||||
function getHistoryItem() {
|
||||
let item = uploads.shift();
|
||||
if (item === undefined || item === "") { return; }
|
||||
let item = uploads.shift()
|
||||
if (item === undefined || item === "") { return }
|
||||
|
||||
fetch(
|
||||
apiEndpoint+"/file/"+item+"/info"
|
||||
).then(resp => {
|
||||
if (!resp.ok) {
|
||||
return Promise.reject();
|
||||
return Promise.reject()
|
||||
}
|
||||
return resp.json();
|
||||
return resp.json()
|
||||
}).then(resp => {
|
||||
let date = new Date(resp.date_upload);
|
||||
document.getElementById("uploaded_files").appendChild(
|
||||
renderFileButton(
|
||||
apiEndpoint,
|
||||
resp.id,
|
||||
resp.name,
|
||||
date.getFullYear()+"-"+("00"+(date.getMonth()+1)).slice(-2)+"-"+("00"+date.getDate()).slice(-2)
|
||||
printDate(new Date(resp.date_upload), true, true, true),
|
||||
)
|
||||
);
|
||||
getHistoryItem();
|
||||
)
|
||||
getHistoryItem()
|
||||
}).catch(err => {
|
||||
console.log("Fetch failed: "+err)
|
||||
getHistoryItem();
|
||||
getHistoryItem()
|
||||
})
|
||||
}
|
||||
|
||||
getHistoryItem();
|
||||
getHistoryItem()
|
||||
|
@@ -1,27 +1,27 @@
|
||||
function UploadProgressBar(uploadManager, queueDiv, file){
|
||||
this.uploadManager = uploadManager;
|
||||
this.file = file;
|
||||
this.name = file.name;
|
||||
this.uploadManager = uploadManager
|
||||
this.file = file
|
||||
this.name = file.name
|
||||
|
||||
this.uploadDiv = document.createElement("a");
|
||||
this.uploadDiv.classList.add("file_button");
|
||||
this.uploadDiv.style.opacity = "0";
|
||||
this.uploadDiv.innerText = "Queued\n" + this.file.name;
|
||||
queueDiv.appendChild(this.uploadDiv);
|
||||
this.uploadDiv = document.createElement("a")
|
||||
this.uploadDiv.classList.add("file_button")
|
||||
this.uploadDiv.style.opacity = "0"
|
||||
this.uploadDiv.innerText = "Queued\n" + this.file.name
|
||||
queueDiv.appendChild(this.uploadDiv)
|
||||
|
||||
// Start uploading the file
|
||||
this.uploadManager.addFile(
|
||||
this.file,
|
||||
this.name,
|
||||
(progress) => { this.onProgress(progress); },
|
||||
(id) => { this.onFinished(id); },
|
||||
(val, msg) => { this.onFailure(val, msg); }
|
||||
);
|
||||
(progress) => { this.onProgress(progress) },
|
||||
(id) => { this.onFinished(id) },
|
||||
(val, msg) => { this.onFailure(val, msg) }
|
||||
)
|
||||
|
||||
// Browsers don't render the transition if the opacity is set and
|
||||
// updated in the same frame. So we have to wait a frame (or more)
|
||||
// before changing the opacity to make sure the transition triggers
|
||||
window.setTimeout(() => {this.uploadDiv.style.opacity = "1";}, 100)
|
||||
window.setTimeout(() => {this.uploadDiv.style.opacity = "1"}, 100)
|
||||
}
|
||||
|
||||
UploadProgressBar.prototype.onProgress = function(progress){
|
||||
@@ -33,7 +33,7 @@ UploadProgressBar.prototype.onProgress = function(progress){
|
||||
+'var(--file_background_color) '+ ((progress*100)+1) +'%)'
|
||||
}
|
||||
UploadProgressBar.prototype.onFinished = function(id){
|
||||
console.log("Upload finished: "+this.file.name+" "+id);
|
||||
console.log("Upload finished: "+this.file.name+" "+id)
|
||||
|
||||
this.uploadDiv.style.background = 'var(--file_background_color)'
|
||||
this.uploadDiv.href = '/u/'+id
|
||||
@@ -55,7 +55,7 @@ UploadProgressBar.prototype.onFinished = function(id){
|
||||
}
|
||||
UploadProgressBar.prototype.onFailure = function(val, msg) {
|
||||
if (val === "") {
|
||||
val = "Could not connect to server";
|
||||
val = "Could not connect to server"
|
||||
}
|
||||
|
||||
this.uploadDiv.innerHTML = "" // Remove uploading progress
|
||||
@@ -65,21 +65,21 @@ UploadProgressBar.prototype.onFailure = function(val, msg) {
|
||||
this.uploadDiv.appendChild(document.createTextNode(msg+" ("+val+")"))
|
||||
this.uploadDiv.appendChild(document.createElement("br"))
|
||||
this.uploadDiv.appendChild(document.createTextNode(this.file.name))
|
||||
console.log(msg);
|
||||
console.log(msg)
|
||||
}
|
||||
|
||||
|
||||
let uploader = null;
|
||||
let shareTitle = "";
|
||||
let shareLink = "";
|
||||
let uploader = null
|
||||
let shareTitle = ""
|
||||
let shareLink = ""
|
||||
|
||||
function handleUploads(files) {
|
||||
if (uploader === null){
|
||||
uploader = new UploadManager(apiEndpoint, uploadsFinished);
|
||||
uploader = new UploadManager(apiEndpoint, uploadsFinished)
|
||||
}
|
||||
|
||||
if (files.length === 0) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
@@ -87,10 +87,10 @@ function handleUploads(files) {
|
||||
uploader,
|
||||
document.getElementById("uploads_queue"),
|
||||
files.item(i)
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
hideShareButtons();
|
||||
hideShareButtons()
|
||||
}
|
||||
|
||||
function uploadsFinished() {
|
||||
@@ -98,35 +98,35 @@ function uploadsFinished() {
|
||||
shareTitle = ""
|
||||
|
||||
// Get the finished uploads from the uploader
|
||||
let uploadLog = uploader.finishedUploads();
|
||||
let uploadLog = uploader.finishedUploads()
|
||||
|
||||
if (uploadLog.length === 1) {
|
||||
shareTitle = "Download "+uploadLog[0].fileName+" here";
|
||||
shareLink = domainURL()+"/u/"+uploadLog[0].fileID;
|
||||
shareTitle = "Download "+uploadLog[0].fileName+" here"
|
||||
shareLink = domainURL()+"/u/"+uploadLog[0].fileID
|
||||
|
||||
showShareButtons();
|
||||
showShareButtons()
|
||||
} else if (uploadLog.length > 1) {
|
||||
let title = uploadLog.length + " files";
|
||||
let title = uploadLog.length + " files"
|
||||
|
||||
createList(
|
||||
title, true,
|
||||
).then(resp => {
|
||||
console.log("Automatic list ID "+resp.id);
|
||||
shareTitle = "View "+title+" here";
|
||||
shareLink = domainURL()+"/l/"+resp.id;
|
||||
console.log("Automatic list ID "+resp.id)
|
||||
shareTitle = "View "+title+" here"
|
||||
shareLink = domainURL()+"/l/"+resp.id
|
||||
|
||||
showShareButtons();
|
||||
showShareButtons()
|
||||
}).catch(err => {
|
||||
alert("Failed to generate link. Please check your internet connection and try again.\nError: "+err);
|
||||
});
|
||||
alert("Failed to generate link. Please check your internet connection and try again.\nError: "+err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function createList(title, anonymous) {
|
||||
let uploads = uploader.finishedUploads();
|
||||
let files = Array();
|
||||
let uploads = uploader.finishedUploads()
|
||||
let files = Array()
|
||||
for (let i = 0; i < uploads.length; i++) {
|
||||
files.push({ "id": uploads[i].fileID });
|
||||
files.push({ "id": uploads[i].fileID })
|
||||
}
|
||||
|
||||
return fetch(
|
||||
@@ -142,34 +142,34 @@ function createList(title, anonymous) {
|
||||
}
|
||||
).then(resp => {
|
||||
if (!resp.ok) {
|
||||
return Promise.reject("HTTP error: "+resp.status);
|
||||
return Promise.reject("HTTP error: "+resp.status)
|
||||
}
|
||||
return resp.json();
|
||||
return resp.json()
|
||||
})
|
||||
}
|
||||
|
||||
function hideShareButtons() {
|
||||
document.getElementById("instruction_3_after").style.display = "none";
|
||||
document.getElementById("instruction_3_after").style.display = "none"
|
||||
}
|
||||
|
||||
function showShareButtons() {
|
||||
document.getElementById("instruction_3_after").style.display = "";
|
||||
document.getElementById("instruction_3_after").style.display = ""
|
||||
|
||||
if (window.navigator && window.navigator.share) {
|
||||
document.getElementById("social_buttons").style.display = "none";
|
||||
document.getElementById("social_buttons").style.display = "none"
|
||||
} else {
|
||||
document.getElementById("navigator_share_button").style.display = "none";
|
||||
document.getElementById("navigator_share_button").style.display = "none"
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink() {
|
||||
if(copyText(shareLink)) {
|
||||
console.log('Text copied');
|
||||
document.querySelector("#btn_copy_link>span").textContent = "Copied!";
|
||||
document.getElementById("btn_copy_link").classList.add("button_highlight");
|
||||
console.log('Text copied')
|
||||
document.querySelector("#btn_copy_link>span").textContent = "Copied!"
|
||||
document.getElementById("btn_copy_link").classList.add("button_highlight")
|
||||
} else {
|
||||
console.log('Copying not supported');
|
||||
alert("Your browser does not support copying text.");
|
||||
console.log('Copying not supported')
|
||||
alert("Your browser does not support copying text.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,33 +179,39 @@ function copyLink() {
|
||||
|
||||
// Relay click event to hidden file field
|
||||
document.getElementById("upload_file_button").onclick = function() {
|
||||
document.getElementById("file_input_field").click();
|
||||
document.getElementById("file_input_field").click()
|
||||
}
|
||||
document.getElementById("file_input_field").onchange = function(evt){
|
||||
// Start uploading the files async
|
||||
window.setTimeout(handleUploads(evt.target.files), 1);
|
||||
window.setTimeout(handleUploads(evt.target.files), 1)
|
||||
|
||||
// This resets the file input field
|
||||
document.getElementById("file_input_field").nodeValue = "";
|
||||
document.getElementById("file_input_field").nodeValue = ""
|
||||
}
|
||||
|
||||
document.getElementById("upload_text_button").onclick = function() {
|
||||
window.location.href = '/t/';
|
||||
window.location.href = '/t/'
|
||||
}
|
||||
|
||||
/*
|
||||
* Drag 'n Drop upload handlers
|
||||
*/
|
||||
|
||||
document.ondragover = function(e) { e.preventDefault(); e.stopPropagation(); }
|
||||
document.ondragenter = function(e) { e.preventDefault(); e.stopPropagation(); }
|
||||
document.ondragover = function(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
document.ondragenter = function(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
document.addEventListener('drop', function(e){
|
||||
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
// Run async to not freeze the page
|
||||
window.setTimeout(handleUploads(e.dataTransfer.files), 1);
|
||||
window.setTimeout(handleUploads(e.dataTransfer.files), 1)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -218,42 +224,65 @@ document.getElementById("btn_social_share").addEventListener("click", function()
|
||||
title: "Pixeldrain",
|
||||
text: shareTitle,
|
||||
url: shareLink
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
document.getElementById("btn_copy_link").addEventListener("click", function() {
|
||||
copyLink();
|
||||
});
|
||||
copyLink()
|
||||
})
|
||||
document.getElementById("btn_open_link").addEventListener("click", function() {
|
||||
window.open(shareLink, '_blank');
|
||||
});
|
||||
window.open(shareLink, '_blank')
|
||||
})
|
||||
document.getElementById("btn_social_email").addEventListener("click", function() {
|
||||
window.open('mailto:please@set.address?subject=File%20on%20pixeldrain&body=' + shareLink);
|
||||
});
|
||||
window.open('mailto:please@set.address?subject=File%20on%20pixeldrain&body=' + shareLink)
|
||||
})
|
||||
document.getElementById("btn_social_twitter").addEventListener("click", function() {
|
||||
window.open('https://twitter.com/share?url=' + shareLink);
|
||||
});
|
||||
window.open('https://twitter.com/share?url=' + shareLink)
|
||||
})
|
||||
document.getElementById("btn_social_facebook").addEventListener("click", function() {
|
||||
window.open('http://www.facebook.com/sharer.php?u=' + shareLink);
|
||||
});
|
||||
window.open('http://www.facebook.com/sharer.php?u=' + shareLink)
|
||||
})
|
||||
document.getElementById("btn_social_reddit").addEventListener("click", function() {
|
||||
window.open('https://www.reddit.com/submit?url=' + shareLink);
|
||||
});
|
||||
window.open('https://www.reddit.com/submit?url=' + shareLink)
|
||||
})
|
||||
document.getElementById("btc_social_tumblr").addEventListener("click", function() {
|
||||
window.open('http://www.tumblr.com/share/link?url=' + shareLink);
|
||||
});
|
||||
window.open('http://www.tumblr.com/share/link?url=' + shareLink)
|
||||
})
|
||||
|
||||
/*
|
||||
* Link copy buttons
|
||||
*/
|
||||
|
||||
function renderListButton(apiURL, id, title, subtitle) {
|
||||
let btn = document.createElement("a")
|
||||
btn.classList = "file_button"
|
||||
btn.href = "/l/"+id
|
||||
btn.target = "_blank"
|
||||
let thumbnail = document.createElement("img")
|
||||
thumbnail.src = apiURL+"/list/"+id+"/thumbnail?width=80&height=80"
|
||||
thumbnail.alt = title
|
||||
let titleSpan = document.createElement("span")
|
||||
titleSpan.classList = "file_button_title"
|
||||
titleSpan.innerText = title
|
||||
let br = document.createElement("br")
|
||||
let subtitleSpan = document.createElement("span")
|
||||
subtitleSpan.classList = "file_button_subtitle"
|
||||
subtitleSpan.innerText = subtitle
|
||||
|
||||
btn.appendChild(thumbnail)
|
||||
btn.appendChild(titleSpan)
|
||||
btn.appendChild(br)
|
||||
btn.appendChild(subtitleSpan)
|
||||
return btn
|
||||
}
|
||||
|
||||
// Create list button
|
||||
document.getElementById("btn_create_list").addEventListener("click", function(evt) {
|
||||
let title = prompt(
|
||||
"You are creating a list containing " + uploader.finishedUploads().length + " files.\n"
|
||||
+ "What do you want to call it?", "My New Album"
|
||||
);
|
||||
)
|
||||
if(title === null){
|
||||
return;
|
||||
return
|
||||
}
|
||||
createList(title, false).then(resp => {
|
||||
document.getElementById("created_lists").appendChild(
|
||||
@@ -263,91 +292,91 @@ document.getElementById("btn_create_list").addEventListener("click", function(ev
|
||||
domainURL()+'/l/'+resp.id,
|
||||
"List creation finished!",
|
||||
)
|
||||
);
|
||||
window.open('/l/'+resp.id, '_blank');
|
||||
)
|
||||
window.open('/l/'+resp.id, '_blank')
|
||||
}).catch(err => {
|
||||
let div = document.createElement("div")
|
||||
div.className = "file_button";
|
||||
div.className = "file_button"
|
||||
div.innerHTML = "List creation failed<br/>"
|
||||
+ "The server responded with:<br/>"
|
||||
+ err;
|
||||
document.getElementById("created_lists").append(div);
|
||||
});
|
||||
});
|
||||
+ err
|
||||
document.getElementById("created_lists").append(div)
|
||||
})
|
||||
})
|
||||
|
||||
let btnCopyLinks = document.getElementById("btn_copy_links");
|
||||
let btnCopyLinks = document.getElementById("btn_copy_links")
|
||||
btnCopyLinks.addEventListener("click", function(){
|
||||
let text = "";
|
||||
let uploads = uploader.finishedUploads();
|
||||
let text = ""
|
||||
let uploads = uploader.finishedUploads()
|
||||
|
||||
// Add the text to the textarea
|
||||
for (let i = 0; i < uploads.length; i++) {
|
||||
// Example: https://pixeldrain.com/u/abcd1234: Some_file.png
|
||||
text += domainURL()+"/u/"+uploads[i].fileID+" "+uploads[i].fileName+"\n";
|
||||
text += domainURL()+"/u/"+uploads[i].fileID+" "+uploads[i].fileName+"\n"
|
||||
}
|
||||
if (shareLink.includes("/l/")) {
|
||||
text += "\n"+shareLink+" All "+uploads.length+" files\n";
|
||||
text += "\n"+shareLink+" All "+uploads.length+" files\n"
|
||||
}
|
||||
|
||||
// Copy the selected text
|
||||
if(copyText(text)){
|
||||
btnCopyLinks.classList.add("button_highlight");
|
||||
btnCopyLinks.classList.add("button_highlight")
|
||||
btnCopyLinks.innerHTML = "Links copied to clipboard!"
|
||||
}else{
|
||||
btnCopyLinks.classList.add("button_red");
|
||||
btnCopyLinks.classList.add("button_red")
|
||||
btnCopyLinks.innerHTML = "Copying links failed"
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
let btnCopyBBCode = document.getElementById("btn_copy_bbcode");
|
||||
let btnCopyBBCode = document.getElementById("btn_copy_bbcode")
|
||||
btnCopyBBCode.addEventListener("click", function(){
|
||||
let text = "";
|
||||
let uploads = uploader.finishedUploads();
|
||||
let text = ""
|
||||
let uploads = uploader.finishedUploads()
|
||||
|
||||
// Add the text to the textarea
|
||||
for (let i = 0; i < uploads.length; i++) {
|
||||
// Example: [url=https://pixeldrain.com/u/abcd1234]Some_file.png[/url]
|
||||
text += "[url="+domainURL()+"/u/"+uploads[i].fileID+"]"+uploads[i].fileName+"[/url]\n";
|
||||
text += "[url="+domainURL()+"/u/"+uploads[i].fileID+"]"+uploads[i].fileName+"[/url]\n"
|
||||
}
|
||||
if (shareLink.includes("/l/")) {
|
||||
text += "\n[url="+shareLink+"]All "+uploads.length+" files[/url]\n";
|
||||
text += "\n[url="+shareLink+"]All "+uploads.length+" files[/url]\n"
|
||||
}
|
||||
|
||||
// Copy the selected text
|
||||
if(copyText(text)){
|
||||
btnCopyBBCode.classList.add("button_highlight");
|
||||
btnCopyBBCode.classList.add("button_highlight")
|
||||
btnCopyBBCode.innerHTML = "BBCode copied to clipboard!"
|
||||
}else{
|
||||
btnCopyBBCode.classList.add("button_red");
|
||||
btnCopyBBCode.classList.add("button_red")
|
||||
btnCopyBBCode.innerHTML = "Copying links failed"
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
let btnCopyMarkdown = document.getElementById("btn_copy_markdown");
|
||||
let btnCopyMarkdown = document.getElementById("btn_copy_markdown")
|
||||
btnCopyMarkdown.addEventListener("click", function(){
|
||||
let text = "";
|
||||
let uploads = uploader.finishedUploads();
|
||||
let text = ""
|
||||
let uploads = uploader.finishedUploads()
|
||||
|
||||
// Add the text to the textarea
|
||||
for (let i = 0; i < uploads.length; i++) {
|
||||
// Example: * [Some_file.png](https://pixeldrain.com/u/abcd1234)
|
||||
|
||||
if (uploads.length > 1) { text += " * "; }
|
||||
text += "["+uploads[i].fileName+"]("+domainURL()+"/u/"+uploads[i].fileID+")\n";
|
||||
if (uploads.length > 1) { text += " * " }
|
||||
text += "["+uploads[i].fileName+"]("+domainURL()+"/u/"+uploads[i].fileID+")\n"
|
||||
}
|
||||
if (shareLink.includes("/l/")) {
|
||||
text += " * [All "+uploads.length+" files]("+shareLink+")\n";
|
||||
text += " * [All "+uploads.length+" files]("+shareLink+")\n"
|
||||
}
|
||||
|
||||
// Copy the selected text
|
||||
if(copyText(text)){
|
||||
btnCopyMarkdown.classList.add("button_highlight");
|
||||
btnCopyMarkdown.classList.add("button_highlight")
|
||||
btnCopyMarkdown.innerHTML = "Markdown copied to clipboard!"
|
||||
}else{
|
||||
btnCopyMarkdown.classList.add("button_red");
|
||||
btnCopyMarkdown.classList.add("button_red")
|
||||
btnCopyMarkdown.innerHTML = "Copying links failed"
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
@@ -359,13 +388,13 @@ document.addEventListener("keydown", function(event){
|
||||
}
|
||||
if (event.keyCode === 67) { // c
|
||||
// Copy links to clipboard
|
||||
document.getElementById("btn_copy_link").click();
|
||||
document.getElementById("btn_copy_link").click()
|
||||
} else if (event.keyCode === 85) { // u
|
||||
// Click the upload button
|
||||
document.getElementById("file_input_field").click();
|
||||
document.getElementById("file_input_field").click()
|
||||
} else if (event.keyCode === 84) { // t
|
||||
// Click the text button
|
||||
document.getElementById("upload_text_button").click();
|
||||
document.getElementById("upload_text_button").click()
|
||||
}
|
||||
console.log(event.keyCode)
|
||||
});
|
||||
})
|
||||
|
@@ -95,3 +95,45 @@ func (wc *WebController) adminGlobalsForm(td *TemplateData, r *http.Request) (f
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// func (wc *WebController) adminFileDeleteForm(td *TemplateData, r *http.Request) (f Form) {
|
||||
// if isAdmin, err := td.PixelAPI.UserIsAdmin(); err != nil {
|
||||
// td.Title = err.Error()
|
||||
// return Form{Title: td.Title}
|
||||
// } else if !isAdmin.IsAdmin {
|
||||
// td.Title = ";)"
|
||||
// return Form{Title: td.Title}
|
||||
// }
|
||||
|
||||
// td.Title = "Admin file removal"
|
||||
// f = Form{
|
||||
// Name: "admin_file_removal",
|
||||
// Title: td.Title,
|
||||
// PreFormHTML: template.HTML("<p>Paste any pixeldrain file links in here to remove them</p>"),
|
||||
// Fields: []Field{
|
||||
// {
|
||||
// Name: "files",
|
||||
// Label: "Files to delete",
|
||||
// Type: FieldTypeTextarea,
|
||||
// },
|
||||
// },
|
||||
// BackLink: "/admin",
|
||||
// SubmitLabel: "Submit",
|
||||
// }
|
||||
|
||||
// if f.ReadInput(r) {
|
||||
// filesText := f.FieldVal("files")
|
||||
|
||||
// // Get all links from the text
|
||||
// strings.Index(filesText, "/u/")
|
||||
|
||||
// if len(f.SubmitMessages) == 0 {
|
||||
// // Request was a success
|
||||
// f.SubmitSuccess = true
|
||||
// f.SubmitMessages = []template.HTML{template.HTML(
|
||||
// fmt.Sprintf("Success! %d values updated", successfulUpdates),
|
||||
// )}
|
||||
// }
|
||||
// }
|
||||
// return f
|
||||
// }
|
||||
|
@@ -2,10 +2,14 @@ package webcontroller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pdmimetype "github.com/Fornaxian/pd_mime_type"
|
||||
|
||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||
"github.com/Fornaxian/log"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@@ -152,3 +156,90 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
|
||||
log.Error("Error executing template file_viewer: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ServeFileViewer controller for GET /s/:id
|
||||
func (wc *WebController) serveSkynetViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var err error
|
||||
templateData := wc.newTemplateData(w, r)
|
||||
|
||||
// Get the first few bytes from the file to probe the content type and
|
||||
// length
|
||||
rq, err := http.NewRequest("GET", "https://siasky.net/"+p.ByName("id"), nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Range header limits the number of bytes which will be read
|
||||
rq.Header.Set("Range", "bytes=0-1023")
|
||||
|
||||
resp, err := wc.httpClient.Do(rq)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 500 {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
return
|
||||
} else if resp.StatusCode >= 400 {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
wc.templates.Get().ExecuteTemplate(w, "file_not_found", templateData)
|
||||
return
|
||||
}
|
||||
|
||||
head, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
return
|
||||
}
|
||||
|
||||
var fileType = resp.Header.Get("Content-Type")
|
||||
if fileType == "application/octet-stream" || fileType == "" {
|
||||
fileType = pdmimetype.Detect(head)
|
||||
}
|
||||
|
||||
// Now get the size of the file from the content-range header
|
||||
contentRange := resp.Header.Get("Content-Range")
|
||||
if contentRange == "" {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
return
|
||||
}
|
||||
contentRange = strings.TrimPrefix(contentRange, "bytes ")
|
||||
size, err := strconv.ParseUint(strings.Split(contentRange, "/")[1], 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
templateData.OGData = ""
|
||||
templateData.Title = fmt.Sprintf("Skylink ~ pixeldrain")
|
||||
templateData.Other = viewerData{
|
||||
Type: "skylink",
|
||||
APIResponse: pixelapi.FileInfo{
|
||||
Success: true,
|
||||
ID: p.ByName("id"),
|
||||
Name: "skynet_file.dat",
|
||||
Size: size,
|
||||
Views: 0,
|
||||
BandwidthUsed: 0,
|
||||
DateUpload: time.Now(),
|
||||
DateLastView: time.Now(),
|
||||
MimeType: fileType,
|
||||
MimeImage: "",
|
||||
ThumbnailHREF: "",
|
||||
Availability: "",
|
||||
},
|
||||
}
|
||||
|
||||
var templateName = "file_viewer"
|
||||
if browserCompat(r.UserAgent()) {
|
||||
templateName = "file_viewer_compat"
|
||||
}
|
||||
|
||||
err = wc.templates.Get().ExecuteTemplate(w, templateName, templateData)
|
||||
if err != nil && !strings.Contains(err.Error(), "broken pipe") {
|
||||
log.Error("Error executing template file_viewer: %s", err)
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -30,6 +31,8 @@ type WebController struct {
|
||||
|
||||
// page-specific variables
|
||||
captchaSiteKey string
|
||||
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// New initializes a new WebController by registering all the request handlers
|
||||
@@ -50,6 +53,7 @@ func New(
|
||||
apiURLInternal: apiURLInternal,
|
||||
apiURLExternal: apiURLExternal,
|
||||
sessionCookieDomain: sessionCookieDomain,
|
||||
httpClient: &http.Client{Timeout: time.Minute * 10},
|
||||
}
|
||||
wc.templates = NewTemplateManager(resourceDir, apiURLExternal, debugMode)
|
||||
wc.templates.ParseTemplates(false)
|
||||
@@ -88,6 +92,7 @@ func New(
|
||||
r.GET(p+"/u/:id" /* */, wc.serveFileViewer)
|
||||
r.GET(p+"/u/:id/preview" /**/, wc.serveFilePreview)
|
||||
r.GET(p+"/l/:id" /* */, wc.serveListViewer)
|
||||
r.GET(p+"/s/:id" /* */, wc.serveSkynetViewer)
|
||||
r.GET(p+"/t" /* */, wc.serveTemplate("paste", false))
|
||||
r.GET(p+"/donation" /* */, wc.serveTemplate("donation", false))
|
||||
r.GET(p+"/widgets" /* */, wc.serveTemplate("widgets", false))
|
||||
|
Reference in New Issue
Block a user