positionsControl
This commit is contained in:
parent
1cbada095e
commit
25e8ed6464
4 changed files with 86 additions and 16 deletions
|
@ -275,6 +275,18 @@ def location_by_slug_geometry(request, location_slug: NonEmptyStr):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@map_api_router.get('/positions/my/', summary="all moving position coordinates",
|
||||||
|
description="get current coordinates of all moving positions owned be the current users",
|
||||||
|
response={200: list[AnyPositionStatusSchema], **API404.dict(), **auth_responses})
|
||||||
|
@api_stats('get_positions')
|
||||||
|
def get_my_positions(request):
|
||||||
|
# no caching for obvious reasons!
|
||||||
|
return [
|
||||||
|
position.serialize_position(request=request)
|
||||||
|
for position in Position.objects.filter(owner=request.user)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@map_api_router.get('/positions/{position_id}/', summary="moving position coordinates",
|
@map_api_router.get('/positions/{position_id}/', summary="moving position coordinates",
|
||||||
description="get current coordinates of a moving position / dynamic location",
|
description="get current coordinates of a moving position / dynamic location",
|
||||||
response={200: AnyPositionStatusSchema, **API404.dict(), **auth_responses})
|
response={200: AnyPositionStatusSchema, **API404.dict(), **auth_responses})
|
||||||
|
@ -295,18 +307,6 @@ def get_position_by_id(request, position_id: AnyPositionID):
|
||||||
return location.serialize_position(request=request)
|
return location.serialize_position(request=request)
|
||||||
|
|
||||||
|
|
||||||
@map_api_router.get('/positions/my/', summary="all moving position coordinates",
|
|
||||||
description="get current coordinates of all moving positions owned be the current users",
|
|
||||||
response={200: list[AnyPositionStatusSchema], **API404.dict(), **auth_responses})
|
|
||||||
@api_stats('get_position')
|
|
||||||
def get_my_positions(request, position_id: AnyPositionID):
|
|
||||||
# no caching for obvious reasons!
|
|
||||||
return [
|
|
||||||
position.serialize_position(request=request)
|
|
||||||
for position in Position.objects.filter(owner=request.user)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class UpdatePositionSchema(BaseSchema):
|
class UpdatePositionSchema(BaseSchema):
|
||||||
coordinates_id: Union[
|
coordinates_id: Union[
|
||||||
Annotated[CustomLocationID, APIField(title="set coordinates")],
|
Annotated[CustomLocationID, APIField(title="set coordinates")],
|
||||||
|
|
|
@ -635,9 +635,12 @@ class Position(CustomLocationProxyMixin, models.Model):
|
||||||
return {
|
return {
|
||||||
'id': 'm:%s' % self.secret,
|
'id': 'm:%s' % self.secret,
|
||||||
'slug': 'm:%s' % self.secret,
|
'slug': 'm:%s' % self.secret,
|
||||||
|
'effective_slug': 'm:%s' % self.secret,
|
||||||
'available': False,
|
'available': False,
|
||||||
'icon': 'my_location',
|
'icon': 'my_location',
|
||||||
|
'effective_icon': 'my_location',
|
||||||
'title': self.name,
|
'title': self.name,
|
||||||
|
'short_name': self.short_name,
|
||||||
'subtitle': _('currently unavailable'),
|
'subtitle': _('currently unavailable'),
|
||||||
}
|
}
|
||||||
# todo: is this good?
|
# todo: is this good?
|
||||||
|
@ -647,8 +650,10 @@ class Position(CustomLocationProxyMixin, models.Model):
|
||||||
'available': True,
|
'available': True,
|
||||||
'id': 'm:%s' % self.secret,
|
'id': 'm:%s' % self.secret,
|
||||||
'slug': 'm:%s' % self.secret,
|
'slug': 'm:%s' % self.secret,
|
||||||
|
'effective_slug': 'm:%s' % self.secret,
|
||||||
'icon': 'my_location',
|
'icon': 'my_location',
|
||||||
'title': self.name,
|
'title': self.name,
|
||||||
|
'short_name': self.short_name,
|
||||||
'subtitle': '%s, %s, %s' % (
|
'subtitle': '%s, %s, %s' % (
|
||||||
_('Position'),
|
_('Position'),
|
||||||
result['title'],
|
result['title'],
|
||||||
|
|
|
@ -1933,7 +1933,7 @@ blink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.symbol-icon {
|
.symbol-icon, .text-icon {
|
||||||
--icon-color: var(--color-primary);
|
--icon-color: var(--color-primary);
|
||||||
> span {
|
> span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -1942,7 +1942,6 @@ blink {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-family: 'Material Symbols Outlined';
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: var(--icon-color);
|
color: var(--icon-color);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
@ -1953,8 +1952,11 @@ blink {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.symbol-icon {
|
||||||
|
font-family: 'Material Symbols Outlined';
|
||||||
|
}
|
||||||
|
|
||||||
&.symbol-icon-interactive {
|
&.symbol-icon-interactive, &.text-icon-interactive {
|
||||||
> span {
|
> span {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
|
|
@ -1765,6 +1765,7 @@ c3nav = {
|
||||||
c3nav._userLocationLayers = {};
|
c3nav._userLocationLayers = {};
|
||||||
c3nav._overlayLayers = {};
|
c3nav._overlayLayers = {};
|
||||||
c3nav._questsLayers = {};
|
c3nav._questsLayers = {};
|
||||||
|
c3nav._positionsLayers = {};
|
||||||
c3nav._firstRouteLevel = null;
|
c3nav._firstRouteLevel = null;
|
||||||
c3nav._labelLayer = L.LayerGroup.collision({margin: 5}).addTo(c3nav.map);
|
c3nav._labelLayer = L.LayerGroup.collision({margin: 5}).addTo(c3nav.map);
|
||||||
c3nav._loadIndicatorLayer = L.LayerGroup.collision({margin: 5}).addTo(c3nav.map);
|
c3nav._loadIndicatorLayer = L.LayerGroup.collision({margin: 5}).addTo(c3nav.map);
|
||||||
|
@ -1791,6 +1792,7 @@ c3nav = {
|
||||||
showCoverageOnHover: false,
|
showCoverageOnHover: false,
|
||||||
iconCreateFunction: makeClusterIconCreate('var(--color-primary)'),
|
iconCreateFunction: makeClusterIconCreate('var(--color-primary)'),
|
||||||
}).addTo(layerGroup);
|
}).addTo(layerGroup);
|
||||||
|
c3nav._positionsLayers[level[0]] = L.layerGroup().addTo(layerGroup);
|
||||||
}
|
}
|
||||||
c3nav._levelControl.finalize();
|
c3nav._levelControl.finalize();
|
||||||
c3nav._levelControl.setLevel(c3nav.initial_level);
|
c3nav._levelControl.setLevel(c3nav.initial_level);
|
||||||
|
@ -1849,6 +1851,7 @@ c3nav = {
|
||||||
|
|
||||||
c3nav._update_overlays();
|
c3nav._update_overlays();
|
||||||
c3nav._update_quests();
|
c3nav._update_quests();
|
||||||
|
c3nav._update_positions();
|
||||||
c3nav._update_loadinfo_labels();
|
c3nav._update_loadinfo_labels();
|
||||||
|
|
||||||
c3nav.map.on('click', c3nav._click_anywhere);
|
c3nav.map.on('click', c3nav._click_anywhere);
|
||||||
|
@ -2278,6 +2281,18 @@ c3nav = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_update_positions: function () {
|
||||||
|
if (!c3nav.map) return;
|
||||||
|
if (c3nav._positionsControl) {
|
||||||
|
if (!c3nav.user_data.has_positions) {
|
||||||
|
c3nav.map.removeControl(c3nav._positionsControl);
|
||||||
|
c3nav._positionsControl = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c3nav.user_data.has_positions) c3nav._positionsControl = (new PositionsControl()).addTo(c3nav.map);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_hasLocationPermission: undefined,
|
_hasLocationPermission: undefined,
|
||||||
hasLocationPermission: function (nocache) {
|
hasLocationPermission: function (nocache) {
|
||||||
if (c3nav._hasLocationPermission === undefined || (nocache !== undefined && nocache === true)) {
|
if (c3nav._hasLocationPermission === undefined || (nocache !== undefined && nocache === true)) {
|
||||||
|
@ -2996,7 +3011,7 @@ QuestsControl = ExpandingControl.extend({
|
||||||
this.reloadQuests().catch(err => console.error(err));
|
this.reloadQuests().catch(err => console.error(err));
|
||||||
},
|
},
|
||||||
|
|
||||||
reloadQuests: async function (force = false) {
|
reloadQuests: async function (force = false) {
|
||||||
const activeQuests = this._activeQuests;
|
const activeQuests = this._activeQuests;
|
||||||
const removed = this._loadedQuests.difference(activeQuests);
|
const removed = this._loadedQuests.difference(activeQuests);
|
||||||
const added = force ? activeQuests : activeQuests.difference(this._loadedQuests);
|
const added = force ? activeQuests : activeQuests.difference(this._loadedQuests);
|
||||||
|
@ -3059,6 +3074,54 @@ QuestsControl = ExpandingControl.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PositionsControl = ToggleControl.extend({
|
||||||
|
options: {
|
||||||
|
position: 'topright',
|
||||||
|
addClasses: 'leaflet-control-positions',
|
||||||
|
enabledIcon: c3nav._map_material_icon('location_on'),
|
||||||
|
disabledIcon: c3nav._map_material_icon('location_off'),
|
||||||
|
storageId: 'positions',
|
||||||
|
onEnable: () => {
|
||||||
|
c3nav._positionsControl.reloadPositions().catch(err => console.error(err));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
reloadPositions: async function () {
|
||||||
|
console.log("abc");
|
||||||
|
for (const level_id in c3nav._positionsLayers) {
|
||||||
|
c3nav._positionsLayers[level_id].clearLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await c3nav_api.get(`map/positions/my/`);
|
||||||
|
|
||||||
|
for (const position of data) {
|
||||||
|
if (!position.available) continue;
|
||||||
|
L.geoJson(position.geometry, {
|
||||||
|
pointToLayer: (geom, latlng) => {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.innerText = position.short_name;
|
||||||
|
return L.marker(latlng, {
|
||||||
|
icon: L.divIcon({
|
||||||
|
className: 'text-icon symbol-icon-interactive',
|
||||||
|
html: span,
|
||||||
|
iconSize: [24, 24],
|
||||||
|
iconAnchor: [12, 12],
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addTo(c3nav._positionsLayers[position.level])
|
||||||
|
.bindPopup(() => {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.innerText = position.name;
|
||||||
|
return span;
|
||||||
|
}, {
|
||||||
|
className: 'data-overlay-popup'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
LegendControl = ExpandingControl.extend({
|
LegendControl = ExpandingControl.extend({
|
||||||
options: {
|
options: {
|
||||||
position: 'topright',
|
position: 'topright',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue