one
Version:
One is a React framework for web, iOS, and Android apps.
191 lines (190 loc) • 5.39 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var image_picker_exports = {};
__export(image_picker_exports, { ImagePicker: () => ImagePicker });
module.exports = __toCommonJS(image_picker_exports);
var import_options = require("./options.cjs");
const granted = Object.freeze({
status: "granted",
granted: true,
canAskAgain: true
});
function acceptFor(mediaTypes) {
const accept = [];
if (mediaTypes.includes("images")) accept.push("image/*");
if (mediaTypes.includes("videos")) accept.push("video/*");
return accept.join(",");
}
function pickFiles(accept, multiple, capture) {
return new Promise((resolve) => {
const input = document.createElement("input");
input.type = "file";
input.accept = accept;
input.multiple = multiple;
if (capture) input.capture = capture;
input.onchange = () => resolve(input.files ? [...input.files] : []);
input.addEventListener("cancel", () => resolve(null));
input.click();
});
}
async function imageSize(file) {
try {
const bitmap = await createImageBitmap(file);
const size = {
width: bitmap.width,
height: bitmap.height
};
bitmap.close();
return size;
} catch {
return {
width: 0,
height: 0
};
}
}
function videoSize(url) {
return new Promise((resolve) => {
const video = document.createElement("video");
video.preload = "metadata";
video.muted = true;
video.onloadedmetadata = () => resolve({
width: video.videoWidth,
height: video.videoHeight
});
video.onerror = () => resolve({
width: 0,
height: 0
});
video.src = url;
});
}
function videoDuration(url) {
return new Promise((resolve) => {
const video = document.createElement("video");
video.preload = "metadata";
video.muted = true;
video.onloadedmetadata = () => resolve(Number.isFinite(video.duration) ? Math.round(video.duration * 1e3) : void 0);
video.onerror = () => resolve(void 0);
video.src = url;
});
}
async function toAsset(file, quality) {
const uri = URL.createObjectURL(file);
const isVideo = file.type.startsWith("video/");
const asset = {
uri,
width: 0,
height: 0,
mimeType: file.type || void 0,
fileName: file.name,
fileSize: file.size,
type: isVideo ? "video" : "image"
};
if (isVideo) {
const url = uri;
const size2 = await videoSize(url);
asset.width = size2.width;
asset.height = size2.height;
const duration = await videoDuration(url);
if (duration !== void 0) asset.duration = duration;
return asset;
}
if (quality < 1) {
const compressed = await compressImage(file, quality);
if (compressed) {
URL.revokeObjectURL(uri);
return compressed;
}
}
const size = await imageSize(file);
asset.width = size.width;
asset.height = size.height;
return asset;
}
async function compressImage(file, quality) {
try {
const bitmap = await createImageBitmap(file);
const canvas = document.createElement("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const context = canvas.getContext("2d");
if (!context) {
bitmap.close();
return null;
}
context.drawImage(bitmap, 0, 0);
bitmap.close();
const blob = await new Promise((resolve) => canvas.toBlob(resolve, "image/jpeg", quality));
if (!blob) return null;
const uri = URL.createObjectURL(blob);
return {
uri,
width: canvas.width,
height: canvas.height,
mimeType: "image/jpeg",
fileName: file.name,
fileSize: blob.size,
type: "image"
};
} catch {
return null;
}
}
async function pick(verb, selectionLimit, mediaTypes, quality, capture) {
if (typeof document === "undefined") {
throw new Error(`ImagePicker.${verb} needs an iOS or Android build`);
}
const files = await pickFiles(acceptFor(mediaTypes), selectionLimit !== 1, capture);
if (!files || files.length === 0) return {
canceled: true,
assets: null
};
const limited = selectionLimit > 0 ? files.slice(0, selectionLimit) : files;
const assets = [];
for (const file of limited) {
assets.push(await toAsset(file, quality));
}
return {
canceled: false,
assets
};
}
function launchLibrary(options = {}) {
const resolved = (0, import_options.resolveImagePickerOptions)(options);
return pick("launchLibrary", resolved.selectionLimit, resolved.mediaTypes, resolved.quality);
}
function launchCamera(options = {}) {
const resolved = (0, import_options.resolveCameraOptions)(options);
return pick("launchCamera", 1, resolved.mediaTypes, resolved.quality, "environment");
}
async function getCameraPermissions() {
return granted;
}
async function requestCameraPermissions() {
return granted;
}
const ImagePicker = Object.freeze({
launchLibrary,
launchCamera,
getCameraPermissions,
requestCameraPermissions
});