UNPKG

@berry-cloud/ngx-unsplash

Version:

Lightweight Angular wrapper for the Unsplash API.

695 lines (688 loc) 27.1 kB
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