diff --git a/.travis.yml b/.travis.yml index c223e789..69c08512 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ dist: trusty language: node_js node_js: -- '8' - '10' - '11' diff --git a/backend/middlewares/GalleryMWs.ts b/backend/middlewares/GalleryMWs.ts index c06ab112..1edac34a 100644 --- a/backend/middlewares/GalleryMWs.ts +++ b/backend/middlewares/GalleryMWs.ts @@ -77,8 +77,6 @@ export class GalleryMWs { delete (m).metadata.positionData; } Utils.removeNullOrEmptyObj(m); - console.log(m); - console.log(Utils.removeNullOrEmptyObj(m)); }); }; diff --git a/backend/model/sql/SearchManager.ts b/backend/model/sql/SearchManager.ts index d750042c..b2c44de1 100644 --- a/backend/model/sql/SearchManager.ts +++ b/backend/model/sql/SearchManager.ts @@ -70,6 +70,16 @@ export class SearchManager implements ISearchManager { .getRawMany()) .map(r => r.name), SearchTypes.photo)); + + result = result.concat(this.encapsulateAutoComplete((await photoRepository + .createQueryBuilder('media') + .select('DISTINCT(media.metadata.caption) as caption') + .where('media.metadata.caption LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .limit(5) + .getRawMany()) + .map(r => r.caption), SearchTypes.photo)); + + result = result.concat(this.encapsulateAutoComplete((await videoRepository .createQueryBuilder('media') .select('DISTINCT(media.name)') @@ -123,6 +133,10 @@ export class SearchManager implements ISearchManager { query.orWhere('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); } + if (!searchType || searchType === SearchTypes.photo) { + query.orWhere('media.metadata.caption LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); + } + if (!searchType || searchType === SearchTypes.position) { query.orWhere('media.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .orWhere('media.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) @@ -176,6 +190,7 @@ export class SearchManager implements ISearchManager { .orWhere('media.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .orWhere('media.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .orWhere('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('media.metadata.caption LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .innerJoinAndSelect('media.directory', 'directory') .limit(10) .getMany(); diff --git a/backend/model/threading/DiskMangerWorker.ts b/backend/model/threading/DiskMangerWorker.ts index e0c8ad8b..4f913861 100644 --- a/backend/model/threading/DiskMangerWorker.ts +++ b/backend/model/threading/DiskMangerWorker.ts @@ -255,7 +255,9 @@ export class DiskMangerWorker { metadata.positionData.state = iptcData.province_or_state; metadata.positionData.city = iptcData.city; } - metadata.caption = iptcData.caption; + if (iptcData.caption) { + metadata.caption = iptcData.caption.replace(/\0/g, '').trim(); + } metadata.keywords = iptcData.keywords || []; metadata.creationDate = (iptcData.date_time ? iptcData.date_time.getTime() : metadata.creationDate); diff --git a/demo/images/IMG_1252.jpg b/demo/images/IMG_1252.jpg index df786458..9b5b8b5d 100644 Binary files a/demo/images/IMG_1252.jpg and b/demo/images/IMG_1252.jpg differ diff --git a/demo/images/IMG_1401.jpg b/demo/images/IMG_1401.jpg index e62d3edd..e257584d 100644 Binary files a/demo/images/IMG_1401.jpg and b/demo/images/IMG_1401.jpg differ diff --git a/demo/images/IMG_5910.jpg b/demo/images/IMG_5910.jpg index 75504018..852d0a68 100644 Binary files a/demo/images/IMG_5910.jpg and b/demo/images/IMG_5910.jpg differ diff --git a/frontend/app/gallery/lightbox/lightbox.gallery.component.css b/frontend/app/gallery/lightbox/lightbox.gallery.component.css index a6460162..da3ab018 100644 --- a/frontend/app/gallery/lightbox/lightbox.gallery.component.css +++ b/frontend/app/gallery/lightbox/lightbox.gallery.component.css @@ -68,7 +68,7 @@ app-gallery-lightbox-photo { opacity: 0; } -#swipeable-container{ +#swipeable-container { height: 100%; } @@ -101,15 +101,25 @@ app-gallery-lightbox-photo { .controls-top { top: 0; - } +.controls-caption { + opacity: 0.5; + top: 0; + position: absolute; + height: initial; + text-align: left; + width: 75%; + padding: 5px 13px; + font-size: 1.5rem; +} .controls-playback { padding-right: 15px; bottom: 0; position: absolute; } + .controls-video { padding-right: 15px; bottom: 0; @@ -117,13 +127,13 @@ app-gallery-lightbox-photo { } .controls-video .oi, -.controls-video input{ +.controls-video input { color: white; cursor: pointer; } -.controls-big-play span{ +.controls-big-play span { font-size: 20vh; position: absolute; top: 50%; @@ -131,12 +141,12 @@ app-gallery-lightbox-photo { transform: translate(-50%, -50%); } -.controls-video input[type=range]{ +.controls-video input[type=range] { padding: 0; margin-top: 6px; } -.controls-video .oi{ +.controls-video .oi { text-align: center; max-width: 45px; margin-left: 10px; diff --git a/frontend/app/gallery/lightbox/lightbox.gallery.component.html b/frontend/app/gallery/lightbox/lightbox.gallery.component.html index f684b3d1..1e4eb6e0 100644 --- a/frontend/app/gallery/lightbox/lightbox.gallery.component.html +++ b/frontend/app/gallery/lightbox/lightbox.gallery.component.html @@ -17,7 +17,7 @@ #controls [style.width.px]="getPhotoFrameWidth()" [ngClass]="!controllersDimmed ? (activePhoto && activePhoto.gridPhoto.isVideo() ? 'dim-controls-video' :'dim-controls'): ''"> - +
{{Title}}
this.activePhoto.gridPhoto.media).metadata.caption; + } } diff --git a/test/backend/unit/model/sql/SearchManager.ts b/test/backend/unit/model/sql/SearchManager.ts index 2e557396..cefccda6 100644 --- a/test/backend/unit/model/sql/SearchManager.ts +++ b/test/backend/unit/model/sql/SearchManager.ts @@ -94,6 +94,7 @@ describe('SearchManager', () => { new AutoCompleteItem('death star', SearchTypes.keyword), new AutoCompleteItem('Padmé Amidala', SearchTypes.keyword), new AutoCompleteItem('Natalie Portman', SearchTypes.keyword), + new AutoCompleteItem('Han Solo\'s dice', SearchTypes.photo), new AutoCompleteItem('Kamino', SearchTypes.position), new AutoCompleteItem('Tatooine', SearchTypes.position), new AutoCompleteItem('wars dir', SearchTypes.directory), @@ -154,6 +155,24 @@ describe('SearchManager', () => { metaFile: [], resultOverflow: false })); + + expect(Utils.clone(await sm.search('han', SearchTypes.photo))).to.deep.equal(Utils.clone({ + searchText: 'han', + searchType: SearchTypes.photo, + directories: [], + media: [p], + metaFile: [], + resultOverflow: false + })); + + expect(Utils.clone(await sm.search('han', SearchTypes.keyword))).to.deep.equal(Utils.clone({ + searchText: 'han', + searchType: SearchTypes.keyword, + directories: [], + media: [], + metaFile: [], + resultOverflow: false + })); }); @@ -199,6 +218,14 @@ describe('SearchManager', () => { metaFile: [], resultOverflow: false })); + + expect(Utils.clone(await sm.instantSearch('han'))).to.deep.equal(Utils.clone({ + searchText: 'han', + directories: [], + media: [p], + metaFile: [], + resultOverflow: false + })); }); diff --git a/test/backend/unit/model/sql/TestHelper.ts b/test/backend/unit/model/sql/TestHelper.ts index 72f317a5..f1024279 100644 --- a/test/backend/unit/model/sql/TestHelper.ts +++ b/test/backend/unit/model/sql/TestHelper.ts @@ -93,6 +93,7 @@ export class TestHelper { public static getPhotoEntry1(dir: DirectoryEntity) { const p = TestHelper.getPhotoEntry(dir); + p.metadata.caption = 'Han Solo\'s dice'; p.metadata.keywords = ['Boba Fett', 'star wars', 'Anakin', 'death star']; p.metadata.positionData.city = 'Mos Eisley'; p.metadata.positionData.country = 'Tatooine';