From 1d41bf2bc5a603a0912510037dec64fec4a70f56 Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Mon, 30 Dec 2019 23:33:07 +0100 Subject: [PATCH] Simple image preview --- css/main.css | 25 +++++++++++++++++++++++++ js/src/mapapi/api_gmaps.js | 2 +- js/src/mapapi/api_openlayers.js | 4 +++- js/src/mapviewmodel.js | 32 +++++++++++++++++++++++--------- js/test/api_gmaps.test.js | 9 +++++---- js/test/api_openlayers.test.js | 10 ++++++---- js/test/mapviewmodel.test.js | 11 +++++------ 7 files changed, 68 insertions(+), 25 deletions(-) diff --git a/css/main.css b/css/main.css index a006cc7..19591b1 100644 --- a/css/main.css +++ b/css/main.css @@ -209,6 +209,10 @@ label[for=user] { max-width: 100%; max-height: 300px; border-radius: 10px; + cursor: pointer; +} +#pimage img:hover { + opacity: 0.7; } #pleft, #pright { display: inline-block; @@ -316,6 +320,27 @@ label[for=user] { -moz-border-radius: 5px; -webkit-border-radius: 5px; } +#modal.image { + padding-top: 0; + background-color: rgba(45, 45, 45, 0.95); + overflow: hidden; +} + +#modal.image #modal-body img { + max-width: 100%; + max-height: 87vh; + height: auto; +} + +#modal.image #modal-body { + width: 90%; + background-color: rgb(45, 45, 45); + text-align: center; +} + +#modal.image #modal-header { + width: 90%; +} button { color: white; diff --git a/js/src/mapapi/api_gmaps.js b/js/src/mapapi/api_gmaps.js index 6bc7b11..9dd794c 100644 --- a/js/src/mapapi/api_gmaps.js +++ b/js/src/mapapi/api_gmaps.js @@ -262,7 +262,7 @@ export default class GoogleMapsApi { * @param {google.maps.Marker} marker */ popupOpen(id, marker) { - this.popup.setContent(this.viewModel.getPopupHtml(id)); + this.popup.setContent(this.viewModel.getPopupElement(id)); this.popup.open(this.map, marker); this.viewModel.model.markerSelect = id; } diff --git a/js/src/mapapi/api_openlayers.js b/js/src/mapapi/api_openlayers.js index 9ae353d..976c21f 100644 --- a/js/src/mapapi/api_openlayers.js +++ b/js/src/mapapi/api_openlayers.js @@ -299,7 +299,8 @@ export default class OpenLayersApi { * @param {Coordinate} coordinate */ popupOpen(id, coordinate) { - this.popup.getElement().firstElementChild.innerHTML = this.viewModel.getPopupHtml(id); + this.popup.getElement().firstElementChild.innerHTML = ''; + this.popup.getElement().firstElementChild.appendChild(this.viewModel.getPopupElement(id)); this.popup.setPosition(coordinate); this.viewModel.model.markerSelect = id; } @@ -310,6 +311,7 @@ export default class OpenLayersApi { popupClose() { // eslint-disable-next-line no-undefined this.popup.setPosition(undefined); + this.popup.getElement().firstElementChild.innerHTML = ''; this.viewModel.model.markerSelect = null; } diff --git a/js/src/mapviewmodel.js b/js/src/mapviewmodel.js index 1f293e6..5a9ab71 100644 --- a/js/src/mapviewmodel.js +++ b/js/src/mapviewmodel.js @@ -21,6 +21,7 @@ import { lang as $, config } from './initializer.js'; import GoogleMapsApi from './mapapi/api_gmaps.js'; import OpenLayersApi from './mapapi/api_openlayers.js'; import ViewModel from './viewmodel.js'; +import uDialog from './dialog.js'; import uObserve from './observe.js'; import uUtils from './utils.js'; @@ -138,9 +139,9 @@ export default class MapViewModel extends ViewModel { /** * Get popup html * @param {number} id Position ID - * @returns {string} + * @returns {HTMLDivElement} */ - getPopupHtml(id) { + getPopupElement(id) { const pos = this.state.currentTrack.positions[id]; const count = this.state.currentTrack.length; let date = '–––'; @@ -152,22 +153,22 @@ export default class MapViewModel extends ViewModel { } let provider = ''; if (pos.provider === 'gps') { - provider = ` (${$._('gps')})`; + provider = ` ${$._('gps')}`; } else if (pos.provider === 'network') { - provider = ` (${$._('network')})`; + provider = ` ${$._('network')}`; } let stats = ''; if (!this.state.showLatest) { stats = `
- ${$._('track')}
+ ${$._('track')}
${$._('ttime')} ${$.getLocaleDuration(pos.totalSeconds)}
${$._('aspeed')} ${$.getLocaleSpeed(pos.totalSpeed, true)}
${$._('tdistance')} ${$.getLocaleDistanceMajor(pos.totalMeters, true)}
`; } - return ` -
${$._('pointof', id + 1, count)}
- `; +
${$._('pointof', id + 1, count)}
`; + const node = document.createElement('div'); + node.setAttribute('id', 'popup'); + node.innerHTML = html; + if (pos.hasImage()) { + const image = node.querySelector('#pimage img'); + image.onclick = () => { + const modal = new uDialog(`image`); + const closeEl = modal.element.querySelector('#modal-close'); + closeEl.onclick = () => modal.destroy(); + modal.element.classList.add('image'); + modal.show(); + } + } + return node; } /** diff --git a/js/test/api_gmaps.test.js b/js/test/api_gmaps.test.js index ad5bade..09f4c43 100644 --- a/js/test/api_gmaps.test.js +++ b/js/test/api_gmaps.test.js @@ -374,15 +374,16 @@ describe('Google Maps map API tests', () => { const id = 1; spyOn(popup, 'setContent').and.callThrough(); spyOn(popup, 'open'); - mockViewModel.getPopupHtml = (i) => `content ${i}`; - spyOn(mockViewModel, 'getPopupHtml').and.callThrough(); + const popupEl = document.createElement('div'); + mockViewModel.getPopupElement = () => popupEl; + spyOn(mockViewModel, 'getPopupElement').and.callThrough(); api.map = new google.maps.Map(container); // when api.popup = popup; api.popupOpen(id, marker); // then - expect(mockViewModel.getPopupHtml).toHaveBeenCalledWith(id); - expect(popup.setContent).toHaveBeenCalledWith(`content ${id}`); + expect(mockViewModel.getPopupElement).toHaveBeenCalledWith(id); + expect(popup.setContent).toHaveBeenCalledWith(popupEl); expect(popup.open).toHaveBeenCalledWith(api.map, marker); expect(api.viewModel.model.markerSelect).toBe(id); }); diff --git a/js/test/api_openlayers.test.js b/js/test/api_openlayers.test.js index 053c164..5d71929 100644 --- a/js/test/api_openlayers.test.js +++ b/js/test/api_openlayers.test.js @@ -521,9 +521,10 @@ describe('Openlayers map API tests', () => { // given const id = 1; const coordinate = [ 1, 2 ]; - mockViewModel.getPopupHtml = (i) => `content ${i}`; + const popupEl = document.createElement('div'); + mockViewModel.getPopupElement = () => popupEl; mockViewModel.model.markerSelect = null; - spyOn(mockViewModel, 'getPopupHtml').and.callThrough(); + spyOn(mockViewModel, 'getPopupElement').and.callThrough(); api.map = mockMap; const popupContainer = document.createElement('div'); const popupContent = document.createElement('div'); @@ -534,14 +535,15 @@ describe('Openlayers map API tests', () => { api.popupOpen(id, coordinate); // then expect(api.popup.getPosition()).toEqual(coordinate); - expect(api.popup.getElement().firstElementChild.innerHTML).toBe(`content ${id}`); + expect(mockViewModel.getPopupElement).toHaveBeenCalledWith(id); + expect(api.popup.getElement().firstElementChild.firstChild).toBe(popupEl); expect(mockViewModel.model.markerSelect).toBe(id); // when api.popupClose(); // then // eslint-disable-next-line no-undefined expect(api.popup.getPosition()).toBe(undefined); - expect(api.popup.getElement().firstElementChild.innerHTML).toBe('content 1'); + expect(api.popup.getElement().firstElementChild.innerHTML).toBe(''); expect(mockViewModel.model.markerSelect).toBe(null); }); }); diff --git a/js/test/mapviewmodel.test.js b/js/test/mapviewmodel.test.js index 6782af6..1474704 100644 --- a/js/test/mapviewmodel.test.js +++ b/js/test/mapviewmodel.test.js @@ -259,8 +259,7 @@ describe('MapViewModel tests', () => { const id = 0; state.currentTrack = TrackFactory.getTrack(2); // when - const html = vm.getPopupHtml(id); - const element = uUtils.nodeFromHtml(html); + const element = vm.getPopupElement(id); // then expect(element).toBeInstanceOf(HTMLDivElement); expect(element.id).toBe('popup'); @@ -275,9 +274,9 @@ describe('MapViewModel tests', () => { state.currentTrack = TrackFactory.getTrack(2); state.showLatest = false; // when - const html = vm.getPopupHtml(id); + const popupEl = vm.getPopupElement(id); // then - expect(html).toContain('id="pright"'); + expect(popupEl.querySelector('#pright')).toBeInstanceOf(HTMLDivElement); }); it('should get popup without stats when track contains only latest positions', () => { @@ -287,9 +286,9 @@ describe('MapViewModel tests', () => { state.currentTrack = TrackFactory.getTrack(2); state.showLatest = true; // when - const html = vm.getPopupHtml(id); + const popupEl = vm.getPopupElement(id); // then - expect(html).not.toContain('id="pright"'); + expect(popupEl.querySelector('#pright')).toBeInstanceOf(HTMLDivElement); }); it('should get marker svg source with given size and without extra border', () => {