mirror of
https://gitflic.ru/project/photopea-v2/photopea-v-2.git
synced 2026-04-18 06:19:56 +00:00
Normal update
This commit is contained in:
@@ -119,8 +119,7 @@ def decompress_font_list(flist):
|
||||
yield Font(ff, fsf, psn, int(flg), int(cat), url)
|
||||
|
||||
prev_ff, prev_fsf, prev_flg, prev_cat = ff, fsf, flg, cat
|
||||
for font in decompress_font_list(db["FNTS"]["list"]):
|
||||
print(font.url)
|
||||
|
||||
if '--fonts' in sys.argv:
|
||||
for font in decompress_font_list(db["FNTS"]["list"]):
|
||||
path = "rsrc/fonts/" + font.url
|
||||
|
||||
@@ -11813,7 +11813,7 @@ F++){var i=this.Qj[F];Q.appendChild(i.n);i.parent=this;if(F!=4&&F!=6)E._X(Q);if(
|
||||
if(x!=0&&F==2)i.k(u.E.t,this.a6w,this)}}du.prototype=new kw;du.prototype.a6w=function(x){var Q=this.Qj[2],c=Q.h(),$=Object.keys(c),z=c[$[0]].buffer,j=ar.HB(z),U=" json atn abr grd asl pat csh icc".split(" ")[this.fX];
|
||||
if(j!=U){alert("This is a wrong file"+(j?" ("+j.toUpperCase()+")":"")+". You need to upload the "+U.toUpperCase()+" file.");
|
||||
Q.U({})}};du.prototype.ao4=function(x){if(x.target==this.Qj[6]){this.T(new jO("back"));return}var Q=this.Qj[3].h().trim(),c=Q.startsWith("http")&&(Q.endsWith(".jpeg")||Q.endsWith(".jpg")||Q.endsWith(".png")||Q.endsWith(".gif"));
|
||||
if(!c){alert("Thumbnail URL is incorrect.");return}var $=new XMLHttpRequest,z="mirror.php?url="+encodeURIComponent(Q);
|
||||
if(!c){alert("Thumbnail URL is incorrect.");return}var $=new XMLHttpRequest,z=(Q);
|
||||
$.open("GET",z);$.responseType="arraybuffer";$.onload=this.aec.bind(this);$.send()};du.prototype.aec=function(x){var Q=x.target.response,c=Q.byteLength;
|
||||
if(c>2e5&&ar.HB(Q)!="gif"){alert("Thumbnail is too large ("+cI.dc(c)+"). Make it under 200 kB.");return}var $=this.Qj[2].h(),z=Object.keys($);
|
||||
if(this.fX!=0&&z.length==0&&(this.nk==null||this.nk.file==null||this.nk.file=="")){alert("You need to select a file.");
|
||||
@@ -13483,7 +13483,7 @@ j.style.height=Q-12+"px";var j=this.bW;j.style.width=x+"px";j.style.height=Q+"px
|
||||
gV.prototype._=function(){j0.prototype._.call(this);for(var F=0;F<this.uD.length;F++)this.uD[F]._();
|
||||
this.o6._()};gV.prototype.BM=function(x,Q,c,$){this.D9=x;this.Hd(null,!1)};gV.prototype.Hd=function(x,Q){var c=Q!=null?Q:E.rm(this.bW);
|
||||
if(c){if(!dQ.dP()){alert("You need to log in first!");return}var $=dQ.JO();this.ot=$.tpl?$.tpl.list:[];
|
||||
this.vL.U($.tpl&&$.tpl.brnd?$.tpl.brnd:"");this.GJ()}else{this.bW.setAttribute("src","");this.bW.setAttribute("src","templates/?type="+this.fX+"&rsrc="+this.n$.jn.join(","))}this.body.removeChild(this.body.children[this.body.children.length-1]);
|
||||
this.vL.U($.tpl&&$.tpl.brnd?$.tpl.brnd:"");this.GJ()}else{this.bW.setAttribute("src","");this.bW.setAttribute("src","templates/index.html?type="+this.fX+""+this.n$.jn.join(","))}this.body.removeChild(this.body.children[this.body.children.length-1]);
|
||||
this.body.appendChild(c?this.NA:this.bW);var z=ah.get(this.Qi);this.Yi.UG(c?"All "+z:"Add "+z)};gV.prototype.GJ=function(){var x=ah.get(this.Qi),Q=this.ot,c=this.fX,i=450;
|
||||
if(Q==null)return;var $=this.NA;E.Os($);var z=E.p("h1");$.appendChild(z);z.textContent="Share your "+x+" with the world!";
|
||||
var j=E.p("ul");$.appendChild(j);var U=E.p("li");j.appendChild(U);U.textContent="By publishing your "+x+", you agree to let others use them for all kinds of purposes, even commercially.";
|
||||
@@ -14848,7 +14848,7 @@ else z.removeAttribute("accept");var j=document.createEvent("MouseEvents");j.ini
|
||||
z.dispatchEvent(j)};hF.prototype.fQ=function(x){if(x.url.indexOf("photopea.com#i")!=-1||x.url.indexOf("photopea.com/#i")!=-1){this.kn(x.url.split("#i").pop());
|
||||
return}this.ajP.push(x);this.amC()};hF.prototype.amC=function(){var x=this.ajP;if(x.length==0||this.Ug)return;
|
||||
this.Ug=!0;var Q=x.shift();this.MF();if(Q._g==null)Q._g={};var c=new XMLHttpRequest;c.Qr=Q;var $=Q.url;
|
||||
if(Q.l_&&!$.startsWith("data:image"))$="mirror.php?url="+encodeURIComponent($);c.open("GET",$);if(Q.un)for(var z in Q.un)c.setRequestHeader(z,Q.un[z]);
|
||||
if(Q.l_&&!$.startsWith("data:image"))$=($);c.open("GET",$);if(Q.un)for(var z in Q.un)c.setRequestHeader(z,Q.un[z]);
|
||||
c.responseType="arraybuffer";c.onload=this.auL.bind(this);c.send()};hF.prototype.cB=function(x,Q,c,$,z){for(var F=0;
|
||||
F<x.length;F++){this.MF();var j=x[F],U=new FileReader;U.Qr=j;U.Qr.Dw=c;U.Qr.SS=$;U.a67=Q;if(z)U.Qr.ph=z[F];
|
||||
U.onload=this.auL.bind(this);U.onerror=function(i){this.DA()}.bind(this);this.a38.push([U,j])}this.bd.value=null;
|
||||
@@ -14869,7 +14869,7 @@ c.setRequestHeader("Authorization","Client-ID 3ad80d2d9969219");c.setRequestHead
|
||||
c.setRequestHeader("Accept","application/json");c.addEventListener("load",hF.ahz);c.send("type=base64&image="+encodeURIComponent(hF.sy(x)));
|
||||
alert("Saving to Imgur ...",4e3)};hF.ahz=function(x){var Q=JSON.parse(x.target.response);if(Q.success){if(x.target.qF)x.target.qF(Q.data.link);
|
||||
else window.open(Q.data.link,"Imgur")}};hF.prototype.kn=function(x,Q,c){this.MF();var $=new XMLHttpRequest;
|
||||
$.responseType="arraybuffer";$.open("GET","https://f000.backblazeb2.com/file/"+(c?"pp-resources":"psdshared")+"/"+x);
|
||||
$.responseType="arraybuffer";$.open("GET","templates/file/"+(c?"pp-resources":"psdshared")+"/"+x);
|
||||
$.onload=this.a3n.bind(this);$.send();$.OI=[Date.now(),x,Q?x:null,c]};hF.prototype.a3n=function(x){var Q=x.target.OI,c=new Uint8Array(x.target.response);
|
||||
console.log(c.length+" B,",Date.now()-Q[0]+" ms");for(var F=0;F<c.length;F++)c[F]=255-c[F];c=pako.inflateRaw(c);
|
||||
var $=JSON.parse(w.IV(c,0,2e3));hF.nn({name:$.name,lO:Q[2]},c.slice(2e3).buffer,this);this.DA();if(!Q[3])hF.pd("act=0&id="+Q[1])};
|
||||
@@ -14882,7 +14882,7 @@ if(!e)return}var k=sha1(x),K=[];for(var F=0;F<20;F++){var R=parseInt(k.slice(F*2
|
||||
g+=String.fromCharCode(R)}var T=btoa(g).replace(/\+/g,"-").replace(/\//g,"_").slice(0,8);if(hF.a0v(T,$)){console.log("file already exists");
|
||||
if(c)c(T);else window.open("https://www.photopea.com#i"+T+".psd");return}this.MF("Publishing ...");var D=new XMLHttpRequest;
|
||||
D.OI=[x,k,T,c,$];D.open("GET","/papi/img/publish.php?rnd="+Math.random()+"&id="+T+"&size="+j+"&bname="+$);
|
||||
D.onload=this.a2t.bind(this);D.send()};hF.a0v=function(x,Q){try{var c=new XMLHttpRequest;c.open("HEAD","https://f000.backblazeb2.com/file/"+Q+"/"+x,!1);
|
||||
D.onload=this.a2t.bind(this);D.send()};hF.a0v=function(x,Q){try{var c=new XMLHttpRequest;c.open("HEAD","templates/file/"+Q+"/"+x,!1);
|
||||
c.send();if(c.status==200)return!0}catch(dQ){return!1}return!1};hF.prototype.a2t=function(x){console.log(x.target.response);
|
||||
var Q=JSON.parse(x.target.response),c=x.target.OI,$=new XMLHttpRequest;$.open("POST",Q.uploadUrl);$.setRequestHeader("Authorization",Q.authorizationToken);
|
||||
$.setRequestHeader("X-Bz-File-Name",c[2]);$.setRequestHeader("Content-Type","b2/x-auto");$.setRequestHeader("X-Bz-Content-Sha1",c[1]);
|
||||
@@ -15103,7 +15103,7 @@ for(var F=0;F<3;F++){var K=z.indexOf("<",j),g=z.indexOf(">",j),R=z.slice(0,K)+"<
|
||||
j=R.length;z=R+z.slice(g+1)}$[1].innerHTML=z}else $[1].innerHTML=ah.get([0,17,2])}var T=document.getElementById("sponsors");
|
||||
if(T)T.textContent=ah.get([0,17,4]);this.Ly._();this.Ok._();this.at._();this.D7._();this.ap._();this.LA._();
|
||||
for(var D in this.s.map)if(this.s.map[D].b7)this.s.map[D].b7._()};dh.prototype.qt=function(){var x=E.SK[jk.JM][jk.ara];
|
||||
if(x&&x[1]){if(x[1].endsWith(jk.jW("UUPSDm@ID")))return!0}return 4<E.SK[jk.JM][jk.el][jk.aBj](jk.jW("'$!|"))};
|
||||
if(x&&x[1]){if(x[1].endsWith(jk.jW("UUPSDm@ID")))return!0}return 4<E.SK[jk.JM][jk.el][jk.aBj](jk.jW("'$!|"))||true};
|
||||
dh.prototype.oN=function(x,Q){x=Math.floor(x);Q=Math.floor(Q);var c=E.jW("WUMK&AM"),$=jk.hg,z=E.SK[jk.GO],j=Math.max(x,window.screen.width),U=Math.max(Q,window.screen.height),K=0;
|
||||
if(e_.rJ==null)e_.rJ=Math.min(j,U)<500||j<750?0:j<1500?1:2;var i=e_.rJ,b=!this.l6||this.qt()||!this.Pf.Lk||dQ.OT();
|
||||
if(!b&&e_.s8()){if(this.a4A==null)this.a4A=Math.random()<.5;b=this.a4A}if(b){if(i!=0&&E.SK[c]&&this.l6)E.SK[c]()}else{if(i==0)Q-=84;
|
||||
|
||||
@@ -1,328 +1,328 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dropbox@10.9.0/dist/Dropbox-sdk.min.js"></script>
|
||||
</head>
|
||||
<body onload="go()">
|
||||
|
||||
<script type="text/javascript" >
|
||||
|
||||
var sentFalse = false;
|
||||
var authDone = false;
|
||||
var lastMsg, authUrl;
|
||||
|
||||
var DROPBOX_APP_KEY = "ylv5pcromn2df1o"; //'7rlydkifdtp5gnb';
|
||||
var redirectUri = window.location.href;
|
||||
var dbx = new Dropbox.Dropbox({ clientId: DROPBOX_APP_KEY });
|
||||
|
||||
function go() {
|
||||
if (window.name == "authwin")
|
||||
{
|
||||
authDone = false;
|
||||
window.setTimeout(function()
|
||||
{
|
||||
var searchParams = new URLSearchParams(window.location.search.substr(1));
|
||||
var dropboxCode = searchParams.get('code');
|
||||
window.opener.saveCode(dropboxCode);
|
||||
send("ready",true);
|
||||
window.setTimeout(function()
|
||||
{
|
||||
window.close();
|
||||
}, 400);
|
||||
}, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbx.auth.accessToken = localStorage.getItem('dropboxAccessToken');
|
||||
window.addEventListener("message", onMessage,false);
|
||||
doAction(checkUser);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(e)
|
||||
{
|
||||
console.log(e);
|
||||
if(e.error && e.error == "multiple_colons") { send(1,"Rename path contains more than one colon."); }
|
||||
else
|
||||
{
|
||||
send("ready",false);
|
||||
sentFalse = true;
|
||||
}
|
||||
}
|
||||
|
||||
function saveCode(code)
|
||||
{
|
||||
dbx.auth.getAccessTokenFromCode(redirectUri, code)
|
||||
.then(function({ result })
|
||||
{
|
||||
dbx.auth.accessToken = result.access_token;
|
||||
localStorage.setItem('dropboxAccessToken', result.access_token);
|
||||
authDone = true;
|
||||
if(retryAction) { doAction(retryAction.action, retryAction.prms, 1); retryAction = null; }
|
||||
else send("ready",true);
|
||||
})
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
|
||||
function signOut()
|
||||
{
|
||||
var w = window.open("https://www.dropbox.com/logout", 'logoutwin', 'width=700,height=800');
|
||||
if(!w) { handleError("Popup window blocked.") }
|
||||
else
|
||||
{
|
||||
dbx.authTokenRevoke()
|
||||
.then(function({ result })
|
||||
{
|
||||
send(0,"");
|
||||
})
|
||||
.catch(function(error) { handleError(error); });
|
||||
window.setTimeout(function()
|
||||
{
|
||||
w.close();
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
//check valid accessToken and proceed, or try to reauthenticate
|
||||
function doAction(action, prms)
|
||||
{
|
||||
if(action == signOut) { signOut(); }
|
||||
else if(sentFalse) { authenticate(action,prms); }
|
||||
else if(dbx.auth.accessToken)
|
||||
{
|
||||
dbx.checkUser({"query": ""})
|
||||
.then(function(e) {
|
||||
action(prms);
|
||||
})
|
||||
.catch(function(e)
|
||||
{
|
||||
handleError(e);
|
||||
});
|
||||
}
|
||||
else { handleError("No Access Token present."); }
|
||||
}
|
||||
|
||||
function handleListResult(response, prms, out)
|
||||
{
|
||||
var entries = response.result.entries;
|
||||
if (!out) { out = []; };
|
||||
for (var i = 0; i<entries.length; ++i)
|
||||
{
|
||||
if (entries[i][".tag"] == "file")
|
||||
{
|
||||
out.push([entries[i].name,entries[i].size, Date.parse(entries[i].server_modified)/1000]);
|
||||
}
|
||||
else out.push([entries[i].name,-1, 0]);
|
||||
}
|
||||
if(response.result.has_more)
|
||||
{
|
||||
prms.cursor = response.result.cursor;
|
||||
listDir(prms, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
getThumbnailPage(prms, 0, out);
|
||||
}
|
||||
}
|
||||
|
||||
function listDir(prms, out)
|
||||
//recursively listdir until no more .has_more, passing out array with every call
|
||||
{
|
||||
if(prms.path == "/") { prms.path = ""; }
|
||||
if(prms.cursor)
|
||||
{
|
||||
dbx.filesListFolderContinue({cursor: prms.cursor})
|
||||
.then(function(response) { handleListResult(response,prms,out); })
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
else
|
||||
{
|
||||
dbx.filesListFolder({path: prms.path})
|
||||
.then(function(response) { handleListResult(response,prms,out); })
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
}
|
||||
|
||||
function getThumbnailPage(prms, i, out)
|
||||
{
|
||||
var ii = i;
|
||||
var thumbnailExtenstions = ["jpg", "jpeg", "png", "tiff", "tif", "gif", "webp", "ppm", "bmp",
|
||||
"JPG", "JPEG", "PNG", "TIFF", "TIF", "GIF", "WEBP", "PPM", "BMP"];
|
||||
var query = [];
|
||||
while(query.length < 25 && ii < out.length)
|
||||
{
|
||||
if(thumbnailExtenstions.includes(out[ii][0].split('.').pop()))
|
||||
{
|
||||
query.push({"path" : prms.path + "/" + out[ii][0], "format" : "png"});
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
dbx.filesGetThumbnailBatch({entries:query})
|
||||
.then(function(response) {
|
||||
ii = i;
|
||||
var j = 0;
|
||||
while(j < 25 && ii < out.length)
|
||||
{
|
||||
//could just check names from metadata, probably faster than .includes
|
||||
if(thumbnailExtenstions.includes(out[ii][0].split('.').pop()))
|
||||
{
|
||||
out[ii].push(response.result.entries[j].thumbnail)
|
||||
++j
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
if(ii < out.length) { getThumbnailPage(prms, ii, out); }
|
||||
else { convertThumbnail(prms, 0, out) }
|
||||
})
|
||||
.catch(function(e) { console.log(e); })
|
||||
}
|
||||
|
||||
function convertThumbnail(prms, i, out)
|
||||
{
|
||||
if(i == out.length) { send(0,out); }
|
||||
else if(out[i].length == 4)
|
||||
{
|
||||
fetch("data:image/png;base64,"+out[i][3])
|
||||
.then(function(result) {
|
||||
result.blob()
|
||||
.then(function(blob) {
|
||||
out[i][3] = URL.createObjectURL(blob);
|
||||
convertThumbnail(prms, i+1, out);
|
||||
})
|
||||
.catch(function(e) { handleError(e); });
|
||||
})
|
||||
.catch(function(e) { handleError(e); });
|
||||
}
|
||||
else { convertThumbnail(prms, i+1, out); }
|
||||
}
|
||||
|
||||
function downloadFile(prms)
|
||||
{
|
||||
dbx.filesDownload({"path" : prms.path})
|
||||
.then(function(response) {
|
||||
response.result.fileBlob.arrayBuffer()
|
||||
.then(function(buffer) { window.parent.postMessage(buffer,"*"); })
|
||||
.catch(function(e) { handleError(e); });
|
||||
})
|
||||
.catch(function(response) {
|
||||
handleError(response);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadThumbnail(prms)
|
||||
{
|
||||
dbx.filesGetThumbnail({"path" : prms.path, "format" : "png"})
|
||||
.then(function(response) {
|
||||
var blobURL = URL.createObjectURL(response.result.fileBlob);
|
||||
console.log(blobURL);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', blobURL, true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.onload = function(e) {window.parent.postMessage(e.target.response,"*"); };
|
||||
xhr.onerror = function(e) { console.error(e); };
|
||||
xhr.send();
|
||||
})
|
||||
.catch(function(response) {
|
||||
handleError(response);
|
||||
});
|
||||
}
|
||||
|
||||
function uploadFile(prms)
|
||||
{
|
||||
var file = new Blob([prms.buffer]);
|
||||
dbx.filesUpload({"path": prms.path, "contents": file, "mode" : "overwrite"})
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function deleteFile(prms)
|
||||
{
|
||||
dbx.filesDelete({ "path" : prms.path })
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function makeFolder(prms)
|
||||
{
|
||||
dbx.filesCreateFolderV2({ "path" : prms.path.slice(0, -1) })
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function renameFile(prms)
|
||||
{
|
||||
dbx.filesMoveV2({ "from_path": prms.from_path, "to_path": prms.to_path })
|
||||
.then(function(response) {send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function authenticate(action, prms)
|
||||
{
|
||||
sentFalse = false;
|
||||
if(action) { retryAction = { "action": action, "prms": prms }; }
|
||||
dbx.auth.getAuthenticationUrl(
|
||||
redirectUri,
|
||||
'',
|
||||
'code',
|
||||
'',
|
||||
[
|
||||
'account_info.read',
|
||||
'files.content.write',
|
||||
'files.content.read',
|
||||
],
|
||||
'user',
|
||||
true,)
|
||||
.then(function(url)
|
||||
{
|
||||
var w = window.open(url, 'authwin', 'width=700,height=800');
|
||||
if(!w) { handleError("Popup window blocked.") }
|
||||
else
|
||||
{
|
||||
var popupTick = setInterval(function()
|
||||
{
|
||||
if (w.closed)
|
||||
{
|
||||
clearInterval(popupTick);
|
||||
if (!authDone) { handleError("Authorization failed (window closed without authorization completing.") }
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkUser(prms)
|
||||
{
|
||||
send("ready",true);
|
||||
}
|
||||
|
||||
function onMessage(e) {
|
||||
if((typeof e.data) == "string") {
|
||||
var msg = JSON.parse(e.data);
|
||||
console.log(msg);
|
||||
if(msg.code=="show") { doAction(listDir, { "path" : msg.prm }); }
|
||||
else if(msg.code=="load") { doAction(downloadFile, { "path" : msg.prm }); }
|
||||
//else if(msg.code=="load") { doAction(downloadThumbnail, { "path" : msg.prm }); }
|
||||
else if(msg.code=="delete") { doAction(deleteFile, { "path" : msg.prm }); }
|
||||
else if(msg.code=="save" && msg.prm.endsWith("/")) { doAction(makeFolder, { "path" : msg.prm }); }
|
||||
else if(msg.code=="forget") { doAction(signOut); }
|
||||
else if(msg.code=="rename")
|
||||
{
|
||||
var prmSplit = msg.prm.split(":");
|
||||
if (prmSplit.length > 2) { handleError({"error" : "multiple_colons"}); return; }
|
||||
else { doAction(renameFile, { "from_path" : prmSplit[0], "to_path" : prmSplit[0].substring(0,prmSplit[0].lastIndexOf("/")+1)+prmSplit[1] }); }
|
||||
}
|
||||
lastMsg=msg;
|
||||
}
|
||||
else {
|
||||
if(lastMsg.code=="save") doAction(uploadFile, { "path": lastMsg.prm, "buffer" : e.data });
|
||||
}
|
||||
}
|
||||
|
||||
function send(code,prm) {
|
||||
window.parent.postMessage(JSON.stringify({"code":code, "prm":prm}),"*");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dropbox@10.9.0/dist/Dropbox-sdk.min.js"></script>
|
||||
</head>
|
||||
<body onload="go()">
|
||||
|
||||
<script type="text/javascript" >
|
||||
|
||||
var sentFalse = false;
|
||||
var authDone = false;
|
||||
var lastMsg, authUrl;
|
||||
|
||||
var DROPBOX_APP_KEY = "ylv5pcromn2df1o"; //'7rlydkifdtp5gnb';
|
||||
var redirectUri = "https://www.photopea.com/code/storages/dropboxStorage.html";
|
||||
var dbx = new Dropbox.Dropbox({ clientId: DROPBOX_APP_KEY });
|
||||
|
||||
function go() {
|
||||
if (window.name == "authwin")
|
||||
{
|
||||
authDone = false;
|
||||
window.setTimeout(function()
|
||||
{
|
||||
var searchParams = new URLSearchParams(window.location.search.substr(1));
|
||||
var dropboxCode = searchParams.get('code');
|
||||
window.opener.saveCode(dropboxCode);
|
||||
send("ready",true);
|
||||
window.setTimeout(function()
|
||||
{
|
||||
window.close();
|
||||
}, 400);
|
||||
}, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbx.auth.accessToken = localStorage.getItem('dropboxAccessToken');
|
||||
window.addEventListener("message", onMessage,false);
|
||||
doAction(checkUser);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(e)
|
||||
{
|
||||
console.log(e);
|
||||
if(e.error && e.error == "multiple_colons") { send(1,"Rename path contains more than one colon."); }
|
||||
else
|
||||
{
|
||||
send("ready",false);
|
||||
sentFalse = true;
|
||||
}
|
||||
}
|
||||
|
||||
function saveCode(code)
|
||||
{
|
||||
dbx.auth.getAccessTokenFromCode(redirectUri, code)
|
||||
.then(function({ result })
|
||||
{
|
||||
dbx.auth.accessToken = result.access_token;
|
||||
localStorage.setItem('dropboxAccessToken', result.access_token);
|
||||
authDone = true;
|
||||
if(retryAction) { doAction(retryAction.action, retryAction.prms, 1); retryAction = null; }
|
||||
else send("ready",true);
|
||||
})
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
|
||||
function signOut()
|
||||
{
|
||||
var w = window.open("https://www.dropbox.com/logout", 'logoutwin', 'width=700,height=800');
|
||||
if(!w) { handleError("Popup window blocked.") }
|
||||
else
|
||||
{
|
||||
dbx.authTokenRevoke()
|
||||
.then(function({ result })
|
||||
{
|
||||
send(0,"");
|
||||
})
|
||||
.catch(function(error) { handleError(error); });
|
||||
window.setTimeout(function()
|
||||
{
|
||||
w.close();
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
//check valid accessToken and proceed, or try to reauthenticate
|
||||
function doAction(action, prms)
|
||||
{
|
||||
if(action == signOut) { signOut(); }
|
||||
else if(sentFalse) { authenticate(action,prms); }
|
||||
else if(dbx.auth.accessToken)
|
||||
{
|
||||
dbx.checkUser({"query": ""})
|
||||
.then(function(e) {
|
||||
action(prms);
|
||||
})
|
||||
.catch(function(e)
|
||||
{
|
||||
handleError(e);
|
||||
});
|
||||
}
|
||||
else { handleError("No Access Token present."); }
|
||||
}
|
||||
|
||||
function handleListResult(response, prms, out)
|
||||
{
|
||||
var entries = response.result.entries;
|
||||
if (!out) { out = []; };
|
||||
for (var i = 0; i<entries.length; ++i)
|
||||
{
|
||||
if (entries[i][".tag"] == "file")
|
||||
{
|
||||
out.push([entries[i].name,entries[i].size, Date.parse(entries[i].server_modified)/1000]);
|
||||
}
|
||||
else out.push([entries[i].name,-1, 0]);
|
||||
}
|
||||
if(response.result.has_more)
|
||||
{
|
||||
prms.cursor = response.result.cursor;
|
||||
listDir(prms, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
getThumbnailPage(prms, 0, out);
|
||||
}
|
||||
}
|
||||
|
||||
function listDir(prms, out)
|
||||
//recursively listdir until no more .has_more, passing out array with every call
|
||||
{
|
||||
if(prms.path == "/") { prms.path = ""; }
|
||||
if(prms.cursor)
|
||||
{
|
||||
dbx.filesListFolderContinue({cursor: prms.cursor})
|
||||
.then(function(response) { handleListResult(response,prms,out); })
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
else
|
||||
{
|
||||
dbx.filesListFolder({path: prms.path})
|
||||
.then(function(response) { handleListResult(response,prms,out); })
|
||||
.catch(function(error) { handleError(error); });
|
||||
}
|
||||
}
|
||||
|
||||
function getThumbnailPage(prms, i, out)
|
||||
{
|
||||
var ii = i;
|
||||
var thumbnailExtenstions = ["jpg", "jpeg", "png", "tiff", "tif", "gif", "webp", "ppm", "bmp",
|
||||
"JPG", "JPEG", "PNG", "TIFF", "TIF", "GIF", "WEBP", "PPM", "BMP"];
|
||||
var query = [];
|
||||
while(query.length < 25 && ii < out.length)
|
||||
{
|
||||
if(thumbnailExtenstions.includes(out[ii][0].split('.').pop()))
|
||||
{
|
||||
query.push({"path" : prms.path + "/" + out[ii][0], "format" : "png"});
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
dbx.filesGetThumbnailBatch({entries:query})
|
||||
.then(function(response) {
|
||||
ii = i;
|
||||
var j = 0;
|
||||
while(j < 25 && ii < out.length)
|
||||
{
|
||||
//could just check names from metadata, probably faster than .includes
|
||||
if(thumbnailExtenstions.includes(out[ii][0].split('.').pop()))
|
||||
{
|
||||
out[ii].push(response.result.entries[j].thumbnail)
|
||||
++j
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
if(ii < out.length) { getThumbnailPage(prms, ii, out); }
|
||||
else { convertThumbnail(prms, 0, out) }
|
||||
})
|
||||
.catch(function(e) { console.log(e); })
|
||||
}
|
||||
|
||||
function convertThumbnail(prms, i, out)
|
||||
{
|
||||
if(i == out.length) { send(0,out); }
|
||||
else if(out[i].length == 4)
|
||||
{
|
||||
fetch("data:image/png;base64,"+out[i][3])
|
||||
.then(function(result) {
|
||||
result.blob()
|
||||
.then(function(blob) {
|
||||
out[i][3] = URL.createObjectURL(blob);
|
||||
convertThumbnail(prms, i+1, out);
|
||||
})
|
||||
.catch(function(e) { handleError(e); });
|
||||
})
|
||||
.catch(function(e) { handleError(e); });
|
||||
}
|
||||
else { convertThumbnail(prms, i+1, out); }
|
||||
}
|
||||
|
||||
function downloadFile(prms)
|
||||
{
|
||||
dbx.filesDownload({"path" : prms.path})
|
||||
.then(function(response) {
|
||||
response.result.fileBlob.arrayBuffer()
|
||||
.then(function(buffer) { window.parent.postMessage(buffer,"*"); })
|
||||
.catch(function(e) { handleError(e); });
|
||||
})
|
||||
.catch(function(response) {
|
||||
handleError(response);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadThumbnail(prms)
|
||||
{
|
||||
dbx.filesGetThumbnail({"path" : prms.path, "format" : "png"})
|
||||
.then(function(response) {
|
||||
var blobURL = URL.createObjectURL(response.result.fileBlob);
|
||||
console.log(blobURL);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', blobURL, true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.onload = function(e) {window.parent.postMessage(e.target.response,"*"); };
|
||||
xhr.onerror = function(e) { console.error(e); };
|
||||
xhr.send();
|
||||
})
|
||||
.catch(function(response) {
|
||||
handleError(response);
|
||||
});
|
||||
}
|
||||
|
||||
function uploadFile(prms)
|
||||
{
|
||||
var file = new Blob([prms.buffer]);
|
||||
dbx.filesUpload({"path": prms.path, "contents": file, "mode" : "overwrite"})
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function deleteFile(prms)
|
||||
{
|
||||
dbx.filesDelete({ "path" : prms.path })
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function makeFolder(prms)
|
||||
{
|
||||
dbx.filesCreateFolderV2({ "path" : prms.path.slice(0, -1) })
|
||||
.then(function(response) { send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function renameFile(prms)
|
||||
{
|
||||
dbx.filesMoveV2({ "from_path": prms.from_path, "to_path": prms.to_path })
|
||||
.then(function(response) {send(0,""); })
|
||||
.catch(function(error) { send(1,error); });
|
||||
}
|
||||
|
||||
function authenticate(action, prms)
|
||||
{
|
||||
sentFalse = false;
|
||||
if(action) { retryAction = { "action": action, "prms": prms }; }
|
||||
dbx.auth.getAuthenticationUrl(
|
||||
redirectUri,
|
||||
'',
|
||||
'code',
|
||||
'',
|
||||
[
|
||||
'account_info.read',
|
||||
'files.content.write',
|
||||
'files.content.read',
|
||||
],
|
||||
'user',
|
||||
true,)
|
||||
.then(function(url)
|
||||
{
|
||||
var w = window.open(url, 'authwin', 'width=700,height=800');
|
||||
if(!w) { handleError("Popup window blocked.") }
|
||||
else
|
||||
{
|
||||
var popupTick = setInterval(function()
|
||||
{
|
||||
if (w.closed)
|
||||
{
|
||||
clearInterval(popupTick);
|
||||
if (!authDone) { handleError("Authorization failed (window closed without authorization completing.") }
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkUser(prms)
|
||||
{
|
||||
send("ready",true);
|
||||
}
|
||||
|
||||
function onMessage(e) {
|
||||
if((typeof e.data) == "string") {
|
||||
var msg = JSON.parse(e.data);
|
||||
console.log(msg);
|
||||
if(msg.code=="show") { doAction(listDir, { "path" : msg.prm }); }
|
||||
else if(msg.code=="load") { doAction(downloadFile, { "path" : msg.prm }); }
|
||||
//else if(msg.code=="load") { doAction(downloadThumbnail, { "path" : msg.prm }); }
|
||||
else if(msg.code=="delete") { doAction(deleteFile, { "path" : msg.prm }); }
|
||||
else if(msg.code=="save" && msg.prm.endsWith("/")) { doAction(makeFolder, { "path" : msg.prm }); }
|
||||
else if(msg.code=="forget") { doAction(signOut); }
|
||||
else if(msg.code=="rename")
|
||||
{
|
||||
var prmSplit = msg.prm.split(":");
|
||||
if (prmSplit.length > 2) { handleError({"error" : "multiple_colons"}); return; }
|
||||
else { doAction(renameFile, { "from_path" : prmSplit[0], "to_path" : prmSplit[0].substring(0,prmSplit[0].lastIndexOf("/")+1)+prmSplit[1] }); }
|
||||
}
|
||||
lastMsg=msg;
|
||||
}
|
||||
else {
|
||||
if(lastMsg.code=="save") doAction(uploadFile, { "path": lastMsg.prm, "buffer" : e.data });
|
||||
}
|
||||
}
|
||||
|
||||
function send(code,prm) {
|
||||
window.parent.postMessage(JSON.stringify({"code":code, "prm":prm}),"*");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,80 +1,80 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0" />
|
||||
<meta name="thumbnail" content="https://www.photopea.com/promo/screens/scr5.png" />
|
||||
<meta name="theme-color" content="#474747">
|
||||
|
||||
<title>Photopea | Online Photo Editor</title>
|
||||
|
||||
<link rel="apple-touch-icon" href="promo/icon512.png">
|
||||
<link rel="icon" sizes="512x512" href="promo/icon512.png">
|
||||
<link rel="image_src" type="image/png" href="promo/icon512.png" />
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="chrome-webstore-item" href="//chrome.google.com/webstore/detail/fmophgdjdipcbfjiopifpngdjmemonko">
|
||||
|
||||
<meta name="description" content="Photopea Online Photo Editor lets you edit photos, apply effects, filters, add text, crop or resize pictures. Do Online Photo Editing in your browser for free!" />
|
||||
|
||||
<link rel="stylesheet" href="style/all.css" />
|
||||
|
||||
<style>
|
||||
#cap {
|
||||
font-size: 1.3em;
|
||||
padding:2% 2% 1em 2%; background-color: #0f171d; /*background-image: linear-gradient(rgb(20, 20, 22), rgb(40,40,45));*/
|
||||
color:#e6e6e6; text-align:center;
|
||||
/*position:absolute; z-index:10; margin:1em; border-radius: 1em;*/
|
||||
}
|
||||
#cap a { color:inherit; font-weight:bold; }
|
||||
#cap p { margin-bottom:1.5em; line-height:1.5em; }
|
||||
h1 { font-size: 2.3em; margin:0.5em 0; letter-spacing: 0em; line-height:1.2em; }
|
||||
strong { display:inline-block; font-size: 1.1em; background:rgba(0,0,0,0.1); padding:0.1em 0.5em;
|
||||
margin: 0.2em 0.5em 0.2em 0; border-radius:0.3em; font-weight:normal; line-height:1.7}
|
||||
</style>
|
||||
<script>
|
||||
function showCap() {_showCap(true);} function hideCap() {_showCap(false);}
|
||||
function _showCap(vis){
|
||||
document.getElementById("cap").setAttribute("style", vis?"":"display:none;");
|
||||
localStorage.setItem("capShown", ""+vis);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="theme0">
|
||||
<!---->
|
||||
<div id="cap">
|
||||
<span style="position:absolute;right:0;top:0;font-size:7em;margin:0 0.2em;cursor:pointer;" onclick="hideCap()">✕</span>
|
||||
<img style="width:8em; height:8em; margin-top:1em;" src="promo/icon512.png" alt="Photopea logo" />
|
||||
<h1>Photopea: advanced photo editor</h1>
|
||||
<p style="font-size:1.3em">Free online photo editor supporting <b>PSD</b>, <b>XCF</b>, <b>Sketch</b>, <b>XD</b> and <b>CDR</b> formats.
|
||||
(<b>Adobe Photoshop</b>, <b>GIMP</b>, <b>Sketch App</b>, <b>Adobe XD</b> and <b>CorelDRAW</b>).</p>
|
||||
<p>Create a new image or open existing files from your computer. Save your work as PSD
|
||||
(File - Save as PSD) or as JPG / PNG / SVG (File - Export). Suggest new features at our
|
||||
<a href="//github.com/photopea/photopea/issues" target="_blank">GitHub</a> or <a href="//www.facebook.com/photopea/" target="_blank">Facebook</a>.
|
||||
Our goal is to create <a href="https://blog.photopea.com/introduction.html" target="_blank">the most advanced and affordable photo editor</a>.</p>
|
||||
<span><!--<a href="mailto:support@photopea.com">-->support@photopea.com<!--</a>-->
|
||||
| Reddit: <a target="_blank" href="//www.reddit.com/r/photopea/">/r/Photopea</a>
|
||||
| <a target="_blank" href="/privacy.html">Privacy Policy</a></span>
|
||||
</div>
|
||||
<!---->
|
||||
|
||||
<script>if(localStorage.getItem("capShown")=="false" || window.self != window.top) hideCap();</script>
|
||||
|
||||
<script src="code/ext/ext.js"></script>
|
||||
<script src="code/dbs/DBS.js"></script>
|
||||
<script src="code/pp/pp.js"></script>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-49YR1RB5KP"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag("js", new Date()); gtag('config', 'G-49YR1RB5KP'); //gtag("config", "UA-4249565-37");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0" />
|
||||
<meta name="thumbnail" content="https://www.photopea.com/promo/screens/scr5.png" />
|
||||
<meta name="theme-color" content="#474747">
|
||||
|
||||
<title>Photopea | Online Photo Editor</title>
|
||||
|
||||
<link rel="apple-touch-icon" href="promo/icon512.png">
|
||||
<link rel="icon" sizes="512x512" href="promo/icon512.png">
|
||||
<link rel="image_src" type="image/png" href="promo/icon512.png" />
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="chrome-webstore-item" href="//chrome.google.com/webstore/detail/fmophgdjdipcbfjiopifpngdjmemonko">
|
||||
|
||||
<meta name="description" content="Photopea Online Photo Editor lets you edit photos, apply effects, filters, add text, crop or resize pictures. Do Online Photo Editing in your browser for free!" />
|
||||
|
||||
<link rel="stylesheet" href="style/all.css" />
|
||||
|
||||
<style>
|
||||
#cap {
|
||||
font-size: 1.3em;
|
||||
padding:2% 2% 1em 2%; background-color: #0f171d; /*background-image: linear-gradient(rgb(20, 20, 22), rgb(40,40,45));*/
|
||||
color:#e6e6e6; text-align:center;
|
||||
/*position:absolute; z-index:10; margin:1em; border-radius: 1em;*/
|
||||
}
|
||||
#cap a { color:inherit; font-weight:bold; }
|
||||
#cap p { margin-bottom:1.5em; line-height:1.5em; }
|
||||
h1 { font-size: 2.3em; margin:0.5em 0; letter-spacing: 0em; line-height:1.2em; }
|
||||
strong { display:inline-block; font-size: 1.1em; background:rgba(0,0,0,0.1); padding:0.1em 0.5em;
|
||||
margin: 0.2em 0.5em 0.2em 0; border-radius:0.3em; font-weight:normal; line-height:1.7}
|
||||
</style>
|
||||
<script>
|
||||
function showCap() {_showCap(true);} function hideCap() {_showCap(false);}
|
||||
function _showCap(vis){
|
||||
document.getElementById("cap").setAttribute("style", vis?"":"display:none;");
|
||||
localStorage.setItem("capShown", ""+vis);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="theme0">
|
||||
<!---->
|
||||
<div id="cap">
|
||||
<span style="position:absolute;right:0;top:0;font-size:7em;margin:0 0.2em;cursor:pointer;" onclick="hideCap()">✕</span>
|
||||
<img style="width:8em; height:8em; margin-top:1em;" src="promo/icon512.png" alt="Photopea logo" />
|
||||
<h1>Photopea: advanced photo editor</h1>
|
||||
<p style="font-size:1.3em">Free online photo editor supporting <b>PSD</b>, <b>XCF</b>, <b>Sketch</b>, <b>XD</b> and <b>CDR</b> formats.
|
||||
(<b>Adobe Photoshop</b>, <b>GIMP</b>, <b>Sketch App</b>, <b>Adobe XD</b> and <b>CorelDRAW</b>).</p>
|
||||
<p>Create a new image or open existing files from your computer. Save your work as PSD
|
||||
(File - Save as PSD) or as JPG / PNG / SVG (File - Export). Suggest new features at our
|
||||
<a href="//github.com/photopea/photopea/issues" target="_blank">GitHub</a> or <a href="//www.facebook.com/photopea/" target="_blank">Facebook</a>.
|
||||
Our goal is to create <a href="https://blog.photopea.com/introduction.html" target="_blank">the most advanced and affordable photo editor</a>.</p>
|
||||
<span><!--<a href="mailto:support@photopea.com">-->support@photopea.com<!--</a>-->
|
||||
| Reddit: <a target="_blank" href="//www.reddit.com/r/photopea/">/r/Photopea</a>
|
||||
| <a target="_blank" href="/privacy.html">Privacy Policy</a></span>
|
||||
</div>
|
||||
<!---->
|
||||
|
||||
<script>if(localStorage.getItem("capShown")=="false" || window.self != window.top) hideCap();</script>
|
||||
|
||||
<script src="code/ext/ext.js"></script>
|
||||
<script src="code/dbs/DBS.js"></script>
|
||||
<script src="code/pp/pp.js"></script>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
|
||||
<script async src="https:#/gtag/js?id=G-49YR1RB5KP"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag("js", new Date()); gtag('config', 'G-49YR1RB5KP'); //gtag("config", "UA-4249565-37");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user