Simple image preview

This commit is contained in:
Bartek Fabiszewski 2019-12-30 23:33:07 +01:00
parent ca5a22678a
commit 1d41bf2bc5
7 changed files with 68 additions and 25 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 = ` (<img class="icon" alt="${$._('gps')}" title="${$._('gps')}" src="images/gps_dark.svg">)`;
provider = ` <img class="icon" alt="${$._('gps')}" title="${$._('gps')}" src="images/gps_dark.svg">`;
} else if (pos.provider === 'network') {
provider = ` (<img class="icon" alt="${$._('network')}" title="${$._('network')}" src="images/network_dark.svg">)`;
provider = ` <img class="icon" alt="${$._('network')}" title="${$._('network')}" src="images/network_dark.svg">`;
}
let stats = '';
if (!this.state.showLatest) {
stats =
`<div id="pright">
<img class="icon" alt="${$._('track')}" src="images/stats_blue.svg" style="padding-left: 3em;"><br>
<img class="icon" alt="${$._('track')}" src="images/stats_blue.svg" style="margin-left: 3em;"><br>
<img class="icon" alt="${$._('ttime')}" title="${$._('ttime')}" src="images/time_blue.svg"> ${$.getLocaleDuration(pos.totalSeconds)}<br>
<img class="icon" alt="${$._('aspeed')}" title="${$._('aspeed')}" src="images/speed_blue.svg"> ${$.getLocaleSpeed(pos.totalSpeed, true)}<br>
<img class="icon" alt="${$._('tdistance')}" title="${$._('tdistance')}" src="images/distance_blue.svg"> ${$.getLocaleDistanceMajor(pos.totalMeters, true)}<br>
</div>`;
}
return `<div id="popup">
<div id="pheader">
const html =
`<div id="pheader">
<div><img alt="${$._('user')}" title="${$._('user')}" src="images/user_dark.svg"> ${uUtils.htmlEncode(pos.username)}</div>
<div><img alt="${$._('track')}" title="${$._('track')}" src="images/route_dark.svg"> ${uUtils.htmlEncode(pos.trackname)}</div>
</div>
@ -181,8 +182,21 @@ export default class MapViewModel extends ViewModel {
${(pos.altitude !== null) ? `<img class="icon" alt="${$._('altitude')}" title="${$._('altitude')}" src="images/altitude_dark.svg">${$.getLocaleAltitude(pos.altitude, true)}<br>` : ''}
${(pos.accuracy !== null) ? `<img class="icon" alt="${$._('accuracy')}" title="${$._('accuracy')}" src="images/accuracy_dark.svg">${$.getLocaleAccuracy(pos.accuracy, true)}${provider}<br>` : ''}
</div>${stats}</div>
<div id="pfooter">${$._('pointof', id + 1, count)}</div>
</div>`;
<div id="pfooter">${$._('pointof', id + 1, count)}</div>`;
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(`<img src="uploads/${pos.image}" alt="image">`);
const closeEl = modal.element.querySelector('#modal-close');
closeEl.onclick = () => modal.destroy();
modal.element.classList.add('image');
modal.show();
}
}
return node;
}
/**

View File

@ -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);
});

View File

@ -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);
});
});

View File

@ -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', () => {