Simple image preview
This commit is contained in:
parent
ca5a22678a
commit
1d41bf2bc5
25
css/main.css
25
css/main.css
@ -209,6 +209,10 @@ label[for=user] {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#pimage img:hover {
|
||||||
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
#pleft, #pright {
|
#pleft, #pright {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -316,6 +320,27 @@ label[for=user] {
|
|||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
-webkit-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 {
|
button {
|
||||||
color: white;
|
color: white;
|
||||||
|
@ -262,7 +262,7 @@ export default class GoogleMapsApi {
|
|||||||
* @param {google.maps.Marker} marker
|
* @param {google.maps.Marker} marker
|
||||||
*/
|
*/
|
||||||
popupOpen(id, 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.popup.open(this.map, marker);
|
||||||
this.viewModel.model.markerSelect = id;
|
this.viewModel.model.markerSelect = id;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,8 @@ export default class OpenLayersApi {
|
|||||||
* @param {Coordinate} coordinate
|
* @param {Coordinate} coordinate
|
||||||
*/
|
*/
|
||||||
popupOpen(id, 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.popup.setPosition(coordinate);
|
||||||
this.viewModel.model.markerSelect = id;
|
this.viewModel.model.markerSelect = id;
|
||||||
}
|
}
|
||||||
@ -310,6 +311,7 @@ export default class OpenLayersApi {
|
|||||||
popupClose() {
|
popupClose() {
|
||||||
// eslint-disable-next-line no-undefined
|
// eslint-disable-next-line no-undefined
|
||||||
this.popup.setPosition(undefined);
|
this.popup.setPosition(undefined);
|
||||||
|
this.popup.getElement().firstElementChild.innerHTML = '';
|
||||||
this.viewModel.model.markerSelect = null;
|
this.viewModel.model.markerSelect = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import { lang as $, config } from './initializer.js';
|
|||||||
import GoogleMapsApi from './mapapi/api_gmaps.js';
|
import GoogleMapsApi from './mapapi/api_gmaps.js';
|
||||||
import OpenLayersApi from './mapapi/api_openlayers.js';
|
import OpenLayersApi from './mapapi/api_openlayers.js';
|
||||||
import ViewModel from './viewmodel.js';
|
import ViewModel from './viewmodel.js';
|
||||||
|
import uDialog from './dialog.js';
|
||||||
import uObserve from './observe.js';
|
import uObserve from './observe.js';
|
||||||
import uUtils from './utils.js';
|
import uUtils from './utils.js';
|
||||||
|
|
||||||
@ -138,9 +139,9 @@ export default class MapViewModel extends ViewModel {
|
|||||||
/**
|
/**
|
||||||
* Get popup html
|
* Get popup html
|
||||||
* @param {number} id Position ID
|
* @param {number} id Position ID
|
||||||
* @returns {string}
|
* @returns {HTMLDivElement}
|
||||||
*/
|
*/
|
||||||
getPopupHtml(id) {
|
getPopupElement(id) {
|
||||||
const pos = this.state.currentTrack.positions[id];
|
const pos = this.state.currentTrack.positions[id];
|
||||||
const count = this.state.currentTrack.length;
|
const count = this.state.currentTrack.length;
|
||||||
let date = '–––';
|
let date = '–––';
|
||||||
@ -152,22 +153,22 @@ export default class MapViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
let provider = '';
|
let provider = '';
|
||||||
if (pos.provider === 'gps') {
|
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') {
|
} 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 = '';
|
let stats = '';
|
||||||
if (!this.state.showLatest) {
|
if (!this.state.showLatest) {
|
||||||
stats =
|
stats =
|
||||||
`<div id="pright">
|
`<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="${$._('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="${$._('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>
|
<img class="icon" alt="${$._('tdistance')}" title="${$._('tdistance')}" src="images/distance_blue.svg"> ${$.getLocaleDistanceMajor(pos.totalMeters, true)}<br>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
return `<div id="popup">
|
const html =
|
||||||
<div id="pheader">
|
`<div id="pheader">
|
||||||
<div><img alt="${$._('user')}" title="${$._('user')}" src="images/user_dark.svg"> ${uUtils.htmlEncode(pos.username)}</div>
|
<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><img alt="${$._('track')}" title="${$._('track')}" src="images/route_dark.svg"> ${uUtils.htmlEncode(pos.trackname)}</div>
|
||||||
</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.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>` : ''}
|
${(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>${stats}</div>
|
||||||
<div id="pfooter">${$._('pointof', id + 1, count)}</div>
|
<div id="pfooter">${$._('pointof', id + 1, count)}</div>`;
|
||||||
</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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -374,15 +374,16 @@ describe('Google Maps map API tests', () => {
|
|||||||
const id = 1;
|
const id = 1;
|
||||||
spyOn(popup, 'setContent').and.callThrough();
|
spyOn(popup, 'setContent').and.callThrough();
|
||||||
spyOn(popup, 'open');
|
spyOn(popup, 'open');
|
||||||
mockViewModel.getPopupHtml = (i) => `content ${i}`;
|
const popupEl = document.createElement('div');
|
||||||
spyOn(mockViewModel, 'getPopupHtml').and.callThrough();
|
mockViewModel.getPopupElement = () => popupEl;
|
||||||
|
spyOn(mockViewModel, 'getPopupElement').and.callThrough();
|
||||||
api.map = new google.maps.Map(container);
|
api.map = new google.maps.Map(container);
|
||||||
// when
|
// when
|
||||||
api.popup = popup;
|
api.popup = popup;
|
||||||
api.popupOpen(id, marker);
|
api.popupOpen(id, marker);
|
||||||
// then
|
// then
|
||||||
expect(mockViewModel.getPopupHtml).toHaveBeenCalledWith(id);
|
expect(mockViewModel.getPopupElement).toHaveBeenCalledWith(id);
|
||||||
expect(popup.setContent).toHaveBeenCalledWith(`content ${id}`);
|
expect(popup.setContent).toHaveBeenCalledWith(popupEl);
|
||||||
expect(popup.open).toHaveBeenCalledWith(api.map, marker);
|
expect(popup.open).toHaveBeenCalledWith(api.map, marker);
|
||||||
expect(api.viewModel.model.markerSelect).toBe(id);
|
expect(api.viewModel.model.markerSelect).toBe(id);
|
||||||
});
|
});
|
||||||
|
@ -521,9 +521,10 @@ describe('Openlayers map API tests', () => {
|
|||||||
// given
|
// given
|
||||||
const id = 1;
|
const id = 1;
|
||||||
const coordinate = [ 1, 2 ];
|
const coordinate = [ 1, 2 ];
|
||||||
mockViewModel.getPopupHtml = (i) => `content ${i}`;
|
const popupEl = document.createElement('div');
|
||||||
|
mockViewModel.getPopupElement = () => popupEl;
|
||||||
mockViewModel.model.markerSelect = null;
|
mockViewModel.model.markerSelect = null;
|
||||||
spyOn(mockViewModel, 'getPopupHtml').and.callThrough();
|
spyOn(mockViewModel, 'getPopupElement').and.callThrough();
|
||||||
api.map = mockMap;
|
api.map = mockMap;
|
||||||
const popupContainer = document.createElement('div');
|
const popupContainer = document.createElement('div');
|
||||||
const popupContent = document.createElement('div');
|
const popupContent = document.createElement('div');
|
||||||
@ -534,14 +535,15 @@ describe('Openlayers map API tests', () => {
|
|||||||
api.popupOpen(id, coordinate);
|
api.popupOpen(id, coordinate);
|
||||||
// then
|
// then
|
||||||
expect(api.popup.getPosition()).toEqual(coordinate);
|
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);
|
expect(mockViewModel.model.markerSelect).toBe(id);
|
||||||
// when
|
// when
|
||||||
api.popupClose();
|
api.popupClose();
|
||||||
// then
|
// then
|
||||||
// eslint-disable-next-line no-undefined
|
// eslint-disable-next-line no-undefined
|
||||||
expect(api.popup.getPosition()).toBe(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);
|
expect(mockViewModel.model.markerSelect).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -259,8 +259,7 @@ describe('MapViewModel tests', () => {
|
|||||||
const id = 0;
|
const id = 0;
|
||||||
state.currentTrack = TrackFactory.getTrack(2);
|
state.currentTrack = TrackFactory.getTrack(2);
|
||||||
// when
|
// when
|
||||||
const html = vm.getPopupHtml(id);
|
const element = vm.getPopupElement(id);
|
||||||
const element = uUtils.nodeFromHtml(html);
|
|
||||||
// then
|
// then
|
||||||
expect(element).toBeInstanceOf(HTMLDivElement);
|
expect(element).toBeInstanceOf(HTMLDivElement);
|
||||||
expect(element.id).toBe('popup');
|
expect(element.id).toBe('popup');
|
||||||
@ -275,9 +274,9 @@ describe('MapViewModel tests', () => {
|
|||||||
state.currentTrack = TrackFactory.getTrack(2);
|
state.currentTrack = TrackFactory.getTrack(2);
|
||||||
state.showLatest = false;
|
state.showLatest = false;
|
||||||
// when
|
// when
|
||||||
const html = vm.getPopupHtml(id);
|
const popupEl = vm.getPopupElement(id);
|
||||||
// then
|
// then
|
||||||
expect(html).toContain('id="pright"');
|
expect(popupEl.querySelector('#pright')).toBeInstanceOf(HTMLDivElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get popup without stats when track contains only latest positions', () => {
|
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.currentTrack = TrackFactory.getTrack(2);
|
||||||
state.showLatest = true;
|
state.showLatest = true;
|
||||||
// when
|
// when
|
||||||
const html = vm.getPopupHtml(id);
|
const popupEl = vm.getPopupElement(id);
|
||||||
// then
|
// 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', () => {
|
it('should get marker svg source with given size and without extra border', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user