@berry-cloud/ngx-unsplash
Version:
Lightweight Angular wrapper for the Unsplash API.
695 lines (688 loc) • 27.1 kB
JavaScript
import * as i0 from '@angular/core';
import { Pipe, NgModule, InjectionToken, Injectable, Inject } from '@angular/core';
import { decode } from 'blurhash';
import { Observable, of } from 'rxjs';
import * as i1 from '@angular/common/http';
import { HttpParams, HttpHeaders } from '@angular/common/http';
import { tap, mergeMap, map } from 'rxjs/operators';
class BlurHashPipe {
/**
* [BlurHash placeholder](https://unsplash.com/documentation#blurhash-placeholders).
*
* Returns a URL of the BlurHash preview and then the URL of photo once the
* photo been downloaded by the browser.
*
* @param photo to download
* @param size to be returned, the default is thumb
* @returns Observable of URL
*/
transform(photo, size = 'thumb') {
return new Observable((observer) => {
// Send URL of blur hash image
observer.next(this.getImageFromBlurHash(photo).toDataURL());
const img = new Image();
img.src = photo.urls[size];
img.onload = () => {
// Send URL of loaded image
observer.next(img.src);
observer.complete();
};
img.onerror = (err) => observer.error(err);
});
}
getImageFromBlurHash(photo) {
const canvas = document.createElement('canvas');
let width = photo.width || 240;
let r = width / 240;
canvas.width = width / r;
canvas.height = (photo.height || 180) / r;
try {
if (photo.blur_hash) {
const pixels = decode(photo.blur_hash, canvas.width, canvas.height);
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(canvas.width, canvas.height);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
}
}
catch { }
return canvas;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: BlurHashPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.2.9", ngImport: i0, type: BlurHashPipe, name: "blurhash" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: BlurHashPipe, decorators: [{
type: Pipe,
args: [{
name: 'blurhash',
}]
}] });
class NgxUnsplashModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgxUnsplashModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.9", ngImport: i0, type: NgxUnsplashModule, declarations: [BlurHashPipe], exports: [BlurHashPipe] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgxUnsplashModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgxUnsplashModule, decorators: [{
type: NgModule,
args: [{
declarations: [BlurHashPipe],
imports: [],
exports: [BlurHashPipe],
}]
}] });
const UNSPLASH_CONFIG = new InjectionToken('unsplash.config');
class UnsplashService {
constructor(http, config) {
this.http = http;
this.searchUrl = 'search/photos';
this.photosUrl = 'photos';
this.randomUrl = 'photos/random';
this.collectionsUrl = 'collections';
this.topicsUrl = 'topics';
this.usersUrl = 'users';
const config$ = config instanceof Observable ? config : of(config);
this.config$ = config$.pipe(tap((config) => {
if (!config) {
throw new Error('Unsplash configuration undefined');
}
if (!config.url) {
throw new Error('Unsplash configuration url undefined');
}
if (!config.authorization) {
throw new Error('Unsplash configuration authorization undefined');
}
}));
}
/**
* [List photos](https://unsplash.com/documentation#list-photos).
*
* Get a single page from the list of all photos.
*
* @param options to be used when getting list of photos
*
* @returns Observable containing a {@link Photo} array
*/
photos(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options.page.toString());
}
if (options?.perPage) {
params = params.set('per_page', options.perPage.toString());
}
if (options?.orderBy) {
params = params.set('order_by', options.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.photosUrl, config);
return this.http.get(url, { params, headers });
}));
}
/**
* [List photos](https://unsplash.com/documentation#list-photos).
*
* Get a single page from the list of all photos.
*
* @param options to be used when getting list of photos
*
* @returns Observable containing a {@link Photo} array
*
* @deprecated Use {@link photos} instead
*/
list(options) {
return this.photos(options);
}
/**
* [Get a photo](https://unsplash.com/documentation#get-a-photo).
*
* Retrieve a single photo.
*
* @param id of the photo
*
* @returns Observable containing the {@link Photo}
*/
photo(id) {
return this.config$.pipe(mergeMap((config) => {
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.photosUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a photo](https://unsplash.com/documentation#get-a-photo).
*
* Retrieve a single photo.
*
* @param id of the photo
*
* @returns Observable containing the {@link Photo}
*
* @deprecated Use {@link photo} instead
*/
get(id) {
return this.photo(id);
}
/**
* [Get random photos](https://unsplash.com/documentation#get-a-random-photo).
*
* Retrieve random photos.
*
* @param options to be used when getting random photos
*
* @returns Observable containing a {@link Photo} array
*/
randomPhoto(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.collections) {
params = params.set('collections', options?.collections);
}
if (options?.topics) {
params = params.set('topics', options?.topics);
}
if (options?.username) {
params = params.set('username', options?.username);
}
if (options?.query) {
params = params.set('query', options?.query);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
if (options?.contentFilter) {
params = params.set('content_filter', options?.contentFilter);
}
if (options?.count) {
params = params.set('count', options?.count);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.randomUrl, config);
return this.http.get(url, { params, headers });
}));
}
/**
* [Get random photos](https://unsplash.com/documentation#get-a-random-photo).
*
* Retrieve random photos.
*
* @param options to be used when getting random photos
*
* @returns Observable containing a {@link Photo} array
*
* @deprecated Use {@link randomPhoto} instead
*/
random(options) {
return this.randomPhoto(options);
}
/**
* [Search photos](https://unsplash.com/documentation#search-photos).
*
* Get a single page of photo results for a query.
*
* @param query to search for
* @param options to be used when searching photos
*
* @returns Observable containing a {@link SearchResult}
*/
searchPhotos(query, options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams().set('query', query);
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
if (options?.collections) {
params = params.set('collections', options?.collections);
}
if (options?.contentFilter) {
params = params.set('content_filter', options?.contentFilter);
}
if (options?.color) {
params = params.set('color', options?.color);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.searchUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Search photos](https://unsplash.com/documentation#search-photos).
*
* Get a single page of photo results for a query.
*
* @param query to search for
* @param options to be used when searching photos
*
* @returns Observable containing a {@link SearchResult}
*
* @deprecated Use {@link searchPhotos} instead
*/
search(query, options) {
return this.searchPhotos(query, options);
}
/**
* [Trigger a download](https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download)
* of a photo.
*
* @param photo to download
*
* @returns Observable containing the {@link Download}
*/
downloadPhoto(photo) {
return this.config$.pipe(mergeMap((config) => {
const headers = this.unsplashHeaders(config);
const photoUrl = new URL(photo.links.download_location);
// Remove the leading slash from the pathname and add the search
const url = this.unsplashUrl(photoUrl.pathname.substring(1) + photoUrl.search, config);
return this.http.get(url, { headers });
}));
}
/**
* [Trigger a download](https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download)
* of a photo.
*
* @param photo to download
*
* @returns Observable containing the {@link Download}
*
* @deprecated Use {@link downloadPhoto} instead
*/
download(photo) {
return this.downloadPhoto(photo);
}
/**
* [List collections](https://unsplash.com/documentation#list-collections).
* Retrieve a list of collections.
*
* @param options to be used when getting collections
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the Unsplash configuration is not provided
*/
collections(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.collectionsUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a collection](https://unsplash.com/documentation#get-a-collection).
* Retrieve a single collection.
*
* @param id of the collection to retrieve
*
* @returns Observable containing a {@link Collection}
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
collection(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a collection's photos](https://unsplash.com/documentation#get-a-collections-photos).
* Retrieve a list of photos in a collection.
*
* @param id of the collection to retrieve photos from
* @param options to be used when getting photos from a collection
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
collectionPhotos(id, options) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List related collections](https://unsplash.com/documentation#list-a-collections-related-collections).
* Retrieve a list of collections related to a particular one.
*
* @param id of the collection to retrieve related collections from
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
relatedCollections(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}/related`, config);
return this.http.get(url, { headers });
}));
}
/**
* [List topics](https://unsplash.com/documentation#list-topics).
* Retrieve a list of topics.
*
* @param options to be used when getting topics
*
* @returns Observable containing a {@link Topic} array
*/
topics(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.ids) {
params = params.set('ids', options?.ids.join(','));
}
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.topicsUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a topic](https://unsplash.com/documentation#get-a-topic).
* Retrieve a single topic.
*
* @param id of the topic to retrieve
*
* @returns Observable containing a {@link Topic}
*
* @throws Error if the topic id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
topic(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Topic id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.topicsUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a topic's photos](https://unsplash.com/documentation#get-a-topics-photos).
* Retrieve a list of photos in a topic.
*
* @param id of the topic to retrieve photos from
* @param options to be used when getting photos from a topic
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the topic id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
topicPhotos(id, options) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Topic id undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.topicsUrl}/${id}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a user](https://unsplash.com/documentation#get-a-user).
* Retrieve public details on a given user.
*
* @param username of the user to retrieve
*
* @returns Observable containing a {@link User}
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
user(username) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a user's portfolio link](https://unsplash.com/documentation#get-a-users-portfolio-link).
* Retrieve a single user’s portfolio link.
*
* @param username of the user to retrieve portfolio link from
*
* @returns Observable containing a {@link User}
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userPortfolio(username) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/portfolio`, config);
return this.http.get(url, { headers });
}), map((response) => response.url));
}
/**
* [List a user’s photos](https://unsplash.com/documentation#list-a-users-photos).
* Retrieve a list of photos uploaded by a user.
*
* @param username of the user to retrieve photos from
* @param options to be used when getting photos from a user
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userPhotos(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
if (options?.stats) {
params = params.set('stats', options?.stats);
}
if (options?.resolution) {
params = params.set('resolution', options?.resolution);
}
if (options?.quantity) {
params = params.set('quantity', options?.quantity);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List a user’s liked photos](https://unsplash.com/documentation#list-a-users-liked-photos).
* Retrieve a list of photos liked by a user.
*
* @param username of the user to retrieve liked photos from
* @param options to be used when getting liked photos from a user
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userLikes(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/likes`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List a user’s collections](https://unsplash.com/documentation#list-a-users-collections).
* Retrieve a list of collections created by the user.
*
* @param username of the user to retrieve collections from
* @param options to be used when getting collections from a user
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userCollections(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/collections`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a user’s statistics](https://unsplash.com/documentation#get-a-users-statistics).
* Retrieve total number of downloads, views and likes of all user’s photos, as well as the historical breakdown and average of these stats in a specific time frame (default is 30 days).
*
* @param username of the user to retrieve statistics from
* @param options to be used when getting statistics from a user
*
* @returns Observable containing a {@link UserStatistics} object
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userStatistics(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.resolution) {
params = params.set('resolution', options?.resolution);
}
if (options?.quantity) {
params = params.set('quantity', options?.quantity);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/statistics`, config);
return this.http.get(url, { headers, params });
}));
}
unsplashUrl(url, config) {
return new URL(url, config.url.endsWith('/') ? config.url : config.url + '/').toString();
}
unsplashHeaders(config) {
return new HttpHeaders().set('authorization', config.authorization);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, deps: [{ token: i1.HttpClient }, { token: UNSPLASH_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
type: Inject,
args: [UNSPLASH_CONFIG]
}] }]; } });
/*
* Public API Surface of ngx-unsplash
*/
/**
* Generated bundle index. Do not edit.
*/
export { BlurHashPipe, NgxUnsplashModule, UNSPLASH_CONFIG, UnsplashService };
//# sourceMappingURL=berry-cloud-ngx-unsplash.mjs.map