mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-03-27 15:55:55 +00:00
Add missing files
This commit is contained in:
parent
cf76e63b5a
commit
cad45bc63f
162
qortal-ui-plugins/plugins/core/components/QortalFileSaver.js
Normal file
162
qortal-ui-plugins/plugins/core/components/QortalFileSaver.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
function saveFile({ data, debug, filename }) {
|
||||||
|
if (debug) console.log("[qortal-file-saver] starting with ", { data, debug, filename });
|
||||||
|
if (!data) throw new Error("[qortal-file-saver] You must pass in data");
|
||||||
|
if (!filename) {
|
||||||
|
if (typeof window !== "undefined" && typeof File !== undefined && data instanceof File) {
|
||||||
|
filename = data.name;
|
||||||
|
}
|
||||||
|
throw new Error("[qortal-file-saver] You must pass in filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
const constructorName = (typeof data === "object" && typeof data.constructor === "function" && data.constructor.name) || null;
|
||||||
|
if (debug) console.log("constructorName:", constructorName);
|
||||||
|
|
||||||
|
const ext = filename.substr(filename.lastIndexOf(".")).toLowerCase();
|
||||||
|
|
||||||
|
const A = ({ href, download }) => {
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = href;
|
||||||
|
a.download = download;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
|
||||||
|
function convertImageToCanvas({ debug, img }) {
|
||||||
|
if (debug) console.log("[qortal-file-saver] starting convertImageToCanvas");
|
||||||
|
const height = img.height;
|
||||||
|
const width = img.width;
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.height = height;
|
||||||
|
canvas.width = width;
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
context.drawImage(img, 0, 0, width, height);
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveHTML({ data, debug, filename }) {
|
||||||
|
if (typeof data === "object" && "outerHTML" in data) {
|
||||||
|
if (debug) console.log("[qortal-file-saver] data appears to be an HTML element, so grabbing it's outer HTML");
|
||||||
|
data = data.outerHTML;
|
||||||
|
}
|
||||||
|
const url = "data:text/html," + encodeURIComponent(data);
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCanvas({ data, debug, filename, imageType }) {
|
||||||
|
const url = data.toDataURL("image/" + imageType);
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveDataOrBlobURL({ url, debug, filename }) {
|
||||||
|
A({ href: url, download: filename }).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveImageAsJPG({ data: img, debug, filename }) {
|
||||||
|
if (debug) console.log("starting saveImageAsJPG");
|
||||||
|
const canvas = convertImageToCanvas({ debug, img });
|
||||||
|
saveCanvasAsJPG({ data: canvas, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveImageAsPNG({ data: img, debug, filename }) {
|
||||||
|
if (debug) console.log("starting saveImageAsPNG");
|
||||||
|
const canvas = convertImageToCanvas({ debug, img });
|
||||||
|
saveCanvasAsPNG({ data: canvas, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveImageAsWebP({ data: img, debug, filename }) {
|
||||||
|
if (debug) console.log("starting saveImageAsWebP");
|
||||||
|
const canvas = convertImageToCanvas({ debug, img });
|
||||||
|
saveCanvasAsWebP({ data: canvas, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCanvasAsJPG({ data, debug, filename }) {
|
||||||
|
saveCanvas({ data, debug, filename, imageType: "jpeg" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCanvasAsPNG({ data, debug, filename }) {
|
||||||
|
saveCanvas({ data, debug, filename, imageType: "png" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCanvasAsWebP({ data, debug, filename }) {
|
||||||
|
saveCanvas({ data, debug, filename, imageType: "webp" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveDSV({ data, debug, delimiter, filename, mediatype }) {
|
||||||
|
if (!Array.isArray(data)) throw new Error("[qortal-saver] data must be an array to save as a CSV");
|
||||||
|
if (!delimiter) throw new Error("[qortal-saver] delimiter must be set");
|
||||||
|
if (!mediatype) throw new Error("[qortal-saver] mediatype must be set");
|
||||||
|
let output = "data:" + mediatype + ";charset=utf-8,";
|
||||||
|
const columns = Array.from(new Set(data.map(Object.keys).flat())).sort();
|
||||||
|
const types = new Set(data.map(it => (Array.isArray(it) ? "array" : typeof it)));
|
||||||
|
const includeHeader = types.has("object");
|
||||||
|
if (debug) console.log("includeHeader:", includeHeader);
|
||||||
|
if (includeHeader) output += columns.map(c => '"' + c.replace(/,/g, "\\,") + '"') + "\n";
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
const row = data[i];
|
||||||
|
if (i !== 0) output += "\n";
|
||||||
|
output += columns.map(col => '"' + row[col].toString().replace(/,/g, "\\,") + '"');
|
||||||
|
}
|
||||||
|
const url = encodeURI(output);
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCSV({ data, debug, filename }) {
|
||||||
|
saveDSV({ data, debug, delimiter: ",", filename, mediatype: "text/csv" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTSV({ data, debug, filename }) {
|
||||||
|
saveDSV({ data, debug, delimiter: "\t", filename, mediatype: "text/tab-separated-values" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveJSON({ data, debug, filename }) {
|
||||||
|
const url = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data, undefined, 2));
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveText({ data, debug, filename }) {
|
||||||
|
const url = "data:text/plain;charset=utf-8," + encodeURIComponent(data);
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveBlob({ data, debug, filename }) {
|
||||||
|
const url = URL.createObjectURL(data);
|
||||||
|
if (debug) console.log("[qortal-file-saver.saveBlob] url:", url);
|
||||||
|
saveDataOrBlobURL({ url, debug, filename });
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext === ".csv") {
|
||||||
|
saveCSV({ data, debug, filename });
|
||||||
|
} else if (ext === ".tsv") {
|
||||||
|
saveTSV({ data, debug, filename });
|
||||||
|
} else if (ext === ".html") {
|
||||||
|
saveHTML({ data, debug, filename });
|
||||||
|
} else if (ext === ".json" || ext === ".geojson" || ext === ".topojson") {
|
||||||
|
saveJSON({ data, debug, filename });
|
||||||
|
} else if (ext === ".txt" || ext === ".js" || ext === ".py") {
|
||||||
|
saveText({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLCanvasElement" && ext === ".png") {
|
||||||
|
saveCanvasAsPNG({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLCanvasElement" && ext === ".jpg") {
|
||||||
|
saveCanvasAsJPG({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLCanvasElement" && ext === ".webp") {
|
||||||
|
saveCanvasAsWebP({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLImageElement" && ext === ".jpg") {
|
||||||
|
saveImageAsJPG({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLImageElement" && ext === ".png") {
|
||||||
|
saveImageAsPNG({ data, debug, filename });
|
||||||
|
} else if (constructorName === "HTMLImageElement" && ext === ".webp") {
|
||||||
|
saveImageAsWebP({ data, debug, filename });
|
||||||
|
} else if (constructorName === "Blob") {
|
||||||
|
saveBlob({ data, debug, filename });
|
||||||
|
} else {
|
||||||
|
throw new Error('[qortal-file-saver] unrecognized extension "' + ext + '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof define === "function" && define.amd)
|
||||||
|
define(function () {
|
||||||
|
return saveFile;
|
||||||
|
});
|
||||||
|
if (typeof module === "object") module.exports = saveFile;
|
||||||
|
if (typeof window === "object") window.saveFile = saveFile;
|
||||||
|
if (typeof self === "object") self.saveFile = saveFile;
|
115
qortal-ui-plugins/plugins/core/components/frag-file-input.js
Normal file
115
qortal-ui-plugins/plugins/core/components/frag-file-input.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { LitElement, html, css } from 'lit'
|
||||||
|
|
||||||
|
import '@material/mwc-button'
|
||||||
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
|
import { translate, translateUnsafeHTML } from 'lit-translate'
|
||||||
|
|
||||||
|
class FragFileInput extends LitElement {
|
||||||
|
static get properties () {
|
||||||
|
return {
|
||||||
|
accept: { type: String },
|
||||||
|
readAs: { type: String }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles () {
|
||||||
|
return css`
|
||||||
|
#drop-area {
|
||||||
|
border: 2px dashed #ccc;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#trigger:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#drop-area.highlight {
|
||||||
|
border-color: var(--mdc-theme-primary, #000);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileInput {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
super()
|
||||||
|
this.readAs = this.readAs || 'Text'
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return html`
|
||||||
|
<div id="drop-area">
|
||||||
|
<slot name="info-text"></slot>
|
||||||
|
<div style="line-height: 40px; text-align: center;">
|
||||||
|
<slot id="trigger" name="inputTrigger" @click=${() => this.shadowRoot.getElementById('fileInput').click()} style="dispay:inline;">
|
||||||
|
<mwc-button><mwc-icon>cloud_upload</mwc-icon><span style="color: var(--black);"> ${translate("fragfile.selectfile")}</span></mwc-button>
|
||||||
|
</slot><br>
|
||||||
|
<span style="text-align: center; padding-top: 4px; color: var(--black);">${translate("fragfile.dragfile")}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="file" id="fileInput" accept="${this.accept}" @change="${e => this.readFile(e.target.files[0])}">
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
readFile (file) {
|
||||||
|
const fr = new FileReader()
|
||||||
|
fr.onload = () => {
|
||||||
|
this.dispatchEvent(new CustomEvent('file-read-success', {
|
||||||
|
detail: { result: fr.result },
|
||||||
|
bubbles: true,
|
||||||
|
composed: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fr['readAs' + this.readAs](file)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated () {
|
||||||
|
this._dropArea = this.shadowRoot.getElementById('drop-area')
|
||||||
|
|
||||||
|
const preventDefaults = e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||||
|
this._dropArea.addEventListener(eventName, preventDefaults, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
const highlight = e => {
|
||||||
|
this._dropArea.classList.add('highlight')
|
||||||
|
}
|
||||||
|
|
||||||
|
const unhighlight = e => {
|
||||||
|
this._dropArea.classList.remove('highlight')
|
||||||
|
}
|
||||||
|
|
||||||
|
;['dragenter', 'dragover'].forEach(eventName => {
|
||||||
|
this._dropArea.addEventListener(eventName, highlight, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
;['dragleave', 'drop'].forEach(eventName => {
|
||||||
|
this._dropArea.addEventListener(eventName, unhighlight, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
this._dropArea.addEventListener('drop', e => {
|
||||||
|
const dt = e.dataTransfer
|
||||||
|
const file = dt.files[0]
|
||||||
|
|
||||||
|
this.readFile(file)
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('frag-file-input', FragFileInput)
|
Loading…
x
Reference in New Issue
Block a user