Replace map grids with hierarchical clustering
This commit is contained in:
parent
762b72100d
commit
ee6a1f7e70
|
|
@ -1,8 +1,10 @@
|
||||||
import maplibregl from "maplibre-gl"
|
import maplibregl from "maplibre-gl"
|
||||||
import {
|
import {
|
||||||
|
clusterCountLabel,
|
||||||
|
clusterExpansionTarget,
|
||||||
clusterSizeClass,
|
clusterSizeClass,
|
||||||
mergeNearbyMapPoints
|
pointFeatureCollection
|
||||||
} from "./map_cluster_points.mjs"
|
} from "./map_cluster_features.mjs"
|
||||||
|
|
||||||
const trackingMinTimeMs = 5000
|
const trackingMinTimeMs = 5000
|
||||||
|
|
||||||
|
|
@ -152,22 +154,6 @@ const areaFeatureCollection = points => ({
|
||||||
.map(areaPolygon)
|
.map(areaPolygon)
|
||||||
})
|
})
|
||||||
|
|
||||||
const clusterFeatureCollection = points => ({
|
|
||||||
type: "FeatureCollection",
|
|
||||||
features: points
|
|
||||||
.filter(point => point.type === "cluster")
|
|
||||||
.map(point => ({
|
|
||||||
type: "Feature",
|
|
||||||
id: point.id,
|
|
||||||
properties: {
|
|
||||||
id: point.id,
|
|
||||||
count: point.count,
|
|
||||||
urgent_count: point.urgent_count || 0
|
|
||||||
},
|
|
||||||
geometry: {type: "Point", coordinates: [point.longitude, point.latitude]}
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
const mapViewport = map => {
|
const mapViewport = map => {
|
||||||
const bounds = map.getBounds()
|
const bounds = map.getBounds()
|
||||||
const container = map.getContainer()
|
const container = map.getContainer()
|
||||||
|
|
@ -300,7 +286,10 @@ const createAidMap = element => {
|
||||||
resizeObserver: null,
|
resizeObserver: null,
|
||||||
markers: [],
|
markers: [],
|
||||||
markerElements: new Map(),
|
markerElements: new Map(),
|
||||||
|
points: [],
|
||||||
|
selectedItemId: null,
|
||||||
clusterExpansionPending: false,
|
clusterExpansionPending: false,
|
||||||
|
pendingMarkerRender: false,
|
||||||
initializedViewport: false,
|
initializedViewport: false,
|
||||||
locationBounds: null,
|
locationBounds: null,
|
||||||
recenterControl: null,
|
recenterControl: null,
|
||||||
|
|
@ -310,7 +299,9 @@ const createAidMap = element => {
|
||||||
areaSelectedId: `${element.id || "aid-map"}-area-selected`,
|
areaSelectedId: `${element.id || "aid-map"}-area-selected`,
|
||||||
clusterSourceId: `${element.id || "aid-map"}-clusters`,
|
clusterSourceId: `${element.id || "aid-map"}-clusters`,
|
||||||
clusterCircleId: `${element.id || "aid-map"}-cluster-circle`,
|
clusterCircleId: `${element.id || "aid-map"}-cluster-circle`,
|
||||||
clusterCountId: `${element.id || "aid-map"}-cluster-count`,
|
serverClusterCircleId: `${element.id || "aid-map"}-server-cluster-circle`,
|
||||||
|
pointCircleId: `${element.id || "aid-map"}-point-circle`,
|
||||||
|
pointSelectedId: `${element.id || "aid-map"}-point-selected`,
|
||||||
statusBadge: element.parentElement?.querySelector("[data-map-status-badge]") || null
|
statusBadge: element.parentElement?.querySelector("[data-map-status-badge]") || null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -458,6 +449,8 @@ const createAidMap = element => {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.highlightRequest = id => {
|
state.highlightRequest = id => {
|
||||||
|
state.selectedItemId = id || null
|
||||||
|
|
||||||
state.markerElements.forEach((element, requestId) => {
|
state.markerElements.forEach((element, requestId) => {
|
||||||
element.classList.toggle("is-selected", requestId === id)
|
element.classList.toggle("is-selected", requestId === id)
|
||||||
})
|
})
|
||||||
|
|
@ -465,6 +458,10 @@ const createAidMap = element => {
|
||||||
if (state.map?.getLayer(state.areaSelectedId)) {
|
if (state.map?.getLayer(state.areaSelectedId)) {
|
||||||
state.map.setFilter(state.areaSelectedId, ["==", ["get", "id"], id || ""])
|
state.map.setFilter(state.areaSelectedId, ["==", ["get", "id"], id || ""])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.map?.getLayer(state.pointSelectedId)) {
|
||||||
|
state.map.setFilter(state.pointSelectedId, ["==", ["get", "id"], id || ""])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.selectRequest = id => {
|
state.selectRequest = id => {
|
||||||
|
|
@ -486,7 +483,6 @@ const createAidMap = element => {
|
||||||
const current = state.element.getBoundingClientRect()
|
const current = state.element.getBoundingClientRect()
|
||||||
if (current.width >= 160 && current.height >= 160) {
|
if (current.width >= 160 && current.height >= 160) {
|
||||||
state.map.resize()
|
state.map.resize()
|
||||||
if (state.element.dataset.discoveryMap === "true") state.renderMarkers()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -517,6 +513,181 @@ const createAidMap = element => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.expandNativeCluster = feature => {
|
||||||
|
const source = state.map?.getSource(state.clusterSourceId)
|
||||||
|
const clusterId = Number(feature?.properties?.cluster_id)
|
||||||
|
if (!source || !Number.isFinite(clusterId)) return
|
||||||
|
|
||||||
|
Promise.resolve(source.getClusterExpansionZoom(clusterId)).then(expansionZoom => {
|
||||||
|
if (!state.active || !state.map) return
|
||||||
|
|
||||||
|
const currentZoom = state.map.getZoom()
|
||||||
|
const targetZoom = clusterExpansionTarget(currentZoom, Number(expansionZoom))
|
||||||
|
|
||||||
|
if (currentZoom >= 21.75 && targetZoom <= 22) {
|
||||||
|
const count = Number(
|
||||||
|
feature.properties?.total_count || feature.properties?.point_count
|
||||||
|
) || 1
|
||||||
|
const label = (state.element.dataset.clusterLabel || "%{count} items")
|
||||||
|
.replace("%{count}", new Intl.NumberFormat(uiLocale()).format(count))
|
||||||
|
|
||||||
|
new maplibregl.Popup({offset: 18})
|
||||||
|
.setLngLat(feature.geometry.coordinates)
|
||||||
|
.setDOMContent(state.popupContent({
|
||||||
|
title: label,
|
||||||
|
location: state.element.dataset.clusterMaxZoomLabel || ""
|
||||||
|
}))
|
||||||
|
.addTo(state.map)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.clusterExpansionPending = true
|
||||||
|
state.map.easeTo({
|
||||||
|
center: feature.geometry.coordinates,
|
||||||
|
zoom: targetZoom,
|
||||||
|
duration: 300
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
state.expandServerCluster = feature => {
|
||||||
|
if (!feature || !state.map) return
|
||||||
|
|
||||||
|
const count = Number(feature.properties?.weight) || 1
|
||||||
|
const requestedZoom = Number(feature.properties?.expansion_zoom)
|
||||||
|
const currentZoom = state.map.getZoom()
|
||||||
|
const expansionZoom = clusterExpansionTarget(
|
||||||
|
currentZoom,
|
||||||
|
Number.isFinite(requestedZoom) ? requestedZoom : currentZoom + 2
|
||||||
|
)
|
||||||
|
|
||||||
|
if (currentZoom >= 21.75 && expansionZoom <= 22) {
|
||||||
|
const label = (state.element.dataset.clusterLabel || "%{count} items")
|
||||||
|
.replace("%{count}", String(count))
|
||||||
|
|
||||||
|
new maplibregl.Popup({offset: 18})
|
||||||
|
.setLngLat(feature.geometry.coordinates)
|
||||||
|
.setDOMContent(state.popupContent({
|
||||||
|
title: label,
|
||||||
|
location: state.element.dataset.clusterMaxZoomLabel || ""
|
||||||
|
}))
|
||||||
|
.addTo(state.map)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.clusterExpansionPending = true
|
||||||
|
state.map.easeTo({
|
||||||
|
center: feature.geometry.coordinates,
|
||||||
|
zoom: expansionZoom,
|
||||||
|
duration: 300
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
state.syncClusterMarkers = () => {
|
||||||
|
state.markers.forEach(marker => marker.remove())
|
||||||
|
state.markers = []
|
||||||
|
|
||||||
|
if (
|
||||||
|
!state.map ||
|
||||||
|
state.element.dataset.discoveryMap !== "true" ||
|
||||||
|
!state.map.getLayer(state.clusterCircleId) ||
|
||||||
|
!state.map.getLayer(state.serverClusterCircleId)
|
||||||
|
) return
|
||||||
|
|
||||||
|
const features = state.map.queryRenderedFeatures({
|
||||||
|
layers: [state.clusterCircleId, state.serverClusterCircleId]
|
||||||
|
})
|
||||||
|
const seen = new Set()
|
||||||
|
|
||||||
|
features.forEach(feature => {
|
||||||
|
const nativeCluster =
|
||||||
|
feature.properties?.cluster === true || feature.properties?.cluster === "true"
|
||||||
|
const key = nativeCluster
|
||||||
|
? `native:${feature.properties.cluster_id}`
|
||||||
|
: `server:${feature.properties?.server_cluster_id || feature.properties?.id}`
|
||||||
|
|
||||||
|
if (seen.has(key)) return
|
||||||
|
seen.add(key)
|
||||||
|
|
||||||
|
const count = Number(
|
||||||
|
nativeCluster
|
||||||
|
? feature.properties?.total_count || feature.properties?.point_count
|
||||||
|
: feature.properties?.weight
|
||||||
|
) || 1
|
||||||
|
const urgentCount = Number(
|
||||||
|
nativeCluster
|
||||||
|
? feature.properties?.urgent_count
|
||||||
|
: feature.properties?.urgent_weight
|
||||||
|
) || 0
|
||||||
|
const button = document.createElement("button")
|
||||||
|
|
||||||
|
button.type = "button"
|
||||||
|
button.className = `request-map-cluster ${clusterSizeClass(count)}`
|
||||||
|
button.dataset.clusterCount = String(count)
|
||||||
|
button.classList.toggle("is-urgent", urgentCount > 0)
|
||||||
|
button.textContent = clusterCountLabel(count, uiLocale())
|
||||||
|
const formattedCount = new Intl.NumberFormat(uiLocale()).format(count)
|
||||||
|
button.setAttribute(
|
||||||
|
"aria-label",
|
||||||
|
(state.element.dataset.clusterLabel || "%{count} items")
|
||||||
|
.replace("%{count}", formattedCount)
|
||||||
|
)
|
||||||
|
button.title = button.getAttribute("aria-label")
|
||||||
|
button.addEventListener("click", event => {
|
||||||
|
event.stopPropagation()
|
||||||
|
if (nativeCluster) {
|
||||||
|
state.expandNativeCluster(feature)
|
||||||
|
} else {
|
||||||
|
state.expandServerCluster(feature)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
state.markers.push(
|
||||||
|
new maplibregl.Marker({element: button})
|
||||||
|
.setLngLat(feature.geometry.coordinates)
|
||||||
|
.addTo(state.map)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
state.syncVisibleAreas = () => {
|
||||||
|
if (!state.map) return
|
||||||
|
|
||||||
|
const areaSource = state.map.getSource(state.areaSourceId)
|
||||||
|
if (!areaSource) return
|
||||||
|
|
||||||
|
let visiblePoints = state.points
|
||||||
|
|
||||||
|
if (state.element.dataset.discoveryMap === "true") {
|
||||||
|
if (!state.map.getSource(state.clusterSourceId)?.loaded()) return
|
||||||
|
|
||||||
|
const visibleIds = new Set(
|
||||||
|
state.map
|
||||||
|
.querySourceFeatures(state.clusterSourceId, {
|
||||||
|
filter: [
|
||||||
|
"all",
|
||||||
|
["!", ["has", "point_count"]],
|
||||||
|
["!=", ["get", "item_type"], "cluster"]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.map(feature => feature.properties?.id)
|
||||||
|
.filter(Boolean)
|
||||||
|
)
|
||||||
|
|
||||||
|
visiblePoints = state.points.filter(point => visibleIds.has(point.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
const signature = visiblePoints
|
||||||
|
.filter(point => !point.exact && Number.isFinite(point.radius_meters))
|
||||||
|
.map(point => point.id)
|
||||||
|
.sort()
|
||||||
|
.join(":")
|
||||||
|
|
||||||
|
if (signature === state.visibleAreaSignature) return
|
||||||
|
state.visibleAreaSignature = signature
|
||||||
|
areaSource.setData(areaFeatureCollection(visiblePoints))
|
||||||
|
}
|
||||||
|
|
||||||
state.renderMarkers = () => {
|
state.renderMarkers = () => {
|
||||||
if (!state.map) return
|
if (!state.map) return
|
||||||
|
|
||||||
|
|
@ -525,22 +696,45 @@ const createAidMap = element => {
|
||||||
state.markerElements.clear()
|
state.markerElements.clear()
|
||||||
|
|
||||||
const points = markerPoints(state.element)
|
const points = markerPoints(state.element)
|
||||||
const displayPoints = mergeNearbyMapPoints(state.map, points)
|
state.points = points
|
||||||
const exactPoints = displayPoints.filter(
|
const pointFeatures = pointFeatureCollection(points)
|
||||||
point => point.type !== "cluster" && (point.exact || !Number.isFinite(point.radius_meters))
|
const areaFeatures =
|
||||||
)
|
state.element.dataset.discoveryMap === "true"
|
||||||
const clusterPoints = displayPoints.filter(point => point.type === "cluster")
|
? emptyFeatureCollection()
|
||||||
const areaFeatures = areaFeatureCollection(displayPoints)
|
: areaFeatureCollection(points)
|
||||||
const clusterFeatures = clusterFeatureCollection(clusterPoints)
|
|
||||||
const bounds = new maplibregl.LngLatBounds()
|
const bounds = new maplibregl.LngLatBounds()
|
||||||
|
|
||||||
exactPoints.forEach(point => bounds.extend([point.longitude, point.latitude]))
|
points.forEach(point => {
|
||||||
areaFeatures.features.forEach(feature => extendBoundsWithFeature(bounds, feature))
|
const clusterBounds = point.bounds
|
||||||
clusterFeatures.features.forEach(feature => bounds.extend(feature.geometry.coordinates))
|
|
||||||
state.locationBounds = displayPoints.length > 0 ? bounds : null
|
|
||||||
|
|
||||||
if (state.map.isStyleLoaded()) {
|
if (
|
||||||
const areaSource = state.map.getSource(state.areaSourceId)
|
clusterBounds &&
|
||||||
|
[clusterBounds.west, clusterBounds.south, clusterBounds.east, clusterBounds.north]
|
||||||
|
.every(value => Number.isFinite(Number(value)))
|
||||||
|
) {
|
||||||
|
bounds.extend([Number(clusterBounds.west), Number(clusterBounds.south)])
|
||||||
|
bounds.extend([Number(clusterBounds.east), Number(clusterBounds.north)])
|
||||||
|
} else {
|
||||||
|
bounds.extend([point.longitude, point.latitude])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
state.locationBounds = points.length > 0 ? bounds : null
|
||||||
|
|
||||||
|
const existingAreaSource = state.map.getSource(state.areaSourceId)
|
||||||
|
const existingPointSource = state.map.getSource(state.clusterSourceId)
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!existingAreaSource || !existingPointSource) &&
|
||||||
|
!state.map.isStyleLoaded()
|
||||||
|
) {
|
||||||
|
state.pendingMarkerRender = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pendingMarkerRender = false
|
||||||
|
|
||||||
|
{
|
||||||
|
const areaSource = existingAreaSource
|
||||||
|
|
||||||
if (areaSource) {
|
if (areaSource) {
|
||||||
areaSource.setData(areaFeatures)
|
areaSource.setData(areaFeatures)
|
||||||
|
|
@ -550,12 +744,14 @@ const createAidMap = element => {
|
||||||
id: state.areaFillId,
|
id: state.areaFillId,
|
||||||
type: "fill",
|
type: "fill",
|
||||||
source: state.areaSourceId,
|
source: state.areaSourceId,
|
||||||
|
minzoom: state.element.dataset.discoveryMap === "true" ? 12 : 0,
|
||||||
paint: {"fill-color": "#278467", "fill-opacity": 0.18}
|
paint: {"fill-color": "#278467", "fill-opacity": 0.18}
|
||||||
})
|
})
|
||||||
state.map.addLayer({
|
state.map.addLayer({
|
||||||
id: state.areaLineId,
|
id: state.areaLineId,
|
||||||
type: "line",
|
type: "line",
|
||||||
source: state.areaSourceId,
|
source: state.areaSourceId,
|
||||||
|
minzoom: state.element.dataset.discoveryMap === "true" ? 12 : 0,
|
||||||
paint: {
|
paint: {
|
||||||
"line-color": "#16725b",
|
"line-color": "#16725b",
|
||||||
"line-width": 2,
|
"line-width": 2,
|
||||||
|
|
@ -566,6 +762,7 @@ const createAidMap = element => {
|
||||||
id: state.areaSelectedId,
|
id: state.areaSelectedId,
|
||||||
type: "line",
|
type: "line",
|
||||||
source: state.areaSourceId,
|
source: state.areaSourceId,
|
||||||
|
minzoom: state.element.dataset.discoveryMap === "true" ? 12 : 0,
|
||||||
filter: ["==", ["get", "id"], ""],
|
filter: ["==", ["get", "id"], ""],
|
||||||
paint: {"line-color": "#d6573b", "line-width": 5}
|
paint: {"line-color": "#d6573b", "line-width": 5}
|
||||||
})
|
})
|
||||||
|
|
@ -588,83 +785,171 @@ const createAidMap = element => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
const pointSource = existingPointSource
|
||||||
|
|
||||||
exactPoints.forEach(point => {
|
if (pointSource) {
|
||||||
const popup = new maplibregl.Popup({offset: 18}).setDOMContent(state.popupContent(point))
|
pointSource.setData(pointFeatures)
|
||||||
const markerColor = point.type === "live" ? "#2563eb" : point.exact ? "#d6573b" : "#278467"
|
} else {
|
||||||
const marker = new maplibregl.Marker({color: markerColor})
|
const sourceOptions = {
|
||||||
.setLngLat([point.longitude, point.latitude])
|
type: "geojson",
|
||||||
.setPopup(popup)
|
data: pointFeatures,
|
||||||
.addTo(state.map)
|
generateId: false
|
||||||
|
}
|
||||||
|
|
||||||
const markerElement = marker.getElement()
|
if (state.element.dataset.discoveryMap === "true") {
|
||||||
markerElement.dataset.markerType = point.type || "request"
|
Object.assign(sourceOptions, {
|
||||||
markerElement.setAttribute("aria-label", point.title || uiText("mapMarkerLabel"))
|
maxzoom: 22,
|
||||||
|
cluster: true,
|
||||||
if (point.id) {
|
clusterRadius: 64,
|
||||||
markerElement.dataset.requestId = point.id
|
clusterMaxZoom: 21,
|
||||||
markerElement.addEventListener("click", () => state.selectRequest(point.id))
|
clusterMinPoints: 2,
|
||||||
state.markerElements.set(point.id, markerElement)
|
clusterProperties: {
|
||||||
}
|
total_count: ["+", ["get", "weight"]],
|
||||||
|
urgent_count: ["+", ["get", "urgent_weight"]]
|
||||||
state.markers.push(marker)
|
|
||||||
})
|
|
||||||
|
|
||||||
clusterPoints.forEach(point => {
|
|
||||||
const element = document.createElement("button")
|
|
||||||
element.type = "button"
|
|
||||||
element.className = `request-map-cluster ${clusterSizeClass(point.count)}`
|
|
||||||
element.dataset.clusterCount = String(point.count)
|
|
||||||
element.classList.toggle("is-urgent", Number(point.urgent_count) > 0)
|
|
||||||
element.textContent = String(point.count)
|
|
||||||
element.setAttribute(
|
|
||||||
"aria-label",
|
|
||||||
(state.element.dataset.clusterLabel || "%{count} requests")
|
|
||||||
.replace("%{count}", String(point.count))
|
|
||||||
)
|
|
||||||
element.title = element.getAttribute("aria-label")
|
|
||||||
element.addEventListener("click", event => {
|
|
||||||
event.stopPropagation()
|
|
||||||
state.clusterExpansionPending = true
|
|
||||||
|
|
||||||
const bounds = point.bounds
|
|
||||||
const hasBounds =
|
|
||||||
bounds &&
|
|
||||||
[bounds.west, bounds.south, bounds.east, bounds.north]
|
|
||||||
.every(value => Number.isFinite(Number(value)))
|
|
||||||
const hasArea =
|
|
||||||
hasBounds &&
|
|
||||||
(Math.abs(Number(bounds.east) - Number(bounds.west)) > 0.000001 ||
|
|
||||||
Math.abs(Number(bounds.north) - Number(bounds.south)) > 0.000001)
|
|
||||||
|
|
||||||
if (hasArea) {
|
|
||||||
state.map.fitBounds(
|
|
||||||
[
|
|
||||||
[Number(bounds.west), Number(bounds.south)],
|
|
||||||
[Number(bounds.east), Number(bounds.north)]
|
|
||||||
],
|
|
||||||
{
|
|
||||||
padding: 72,
|
|
||||||
maxZoom: Math.min(state.map.getZoom() + 5, 18),
|
|
||||||
duration: 300
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
} else {
|
|
||||||
state.map.easeTo({
|
|
||||||
center: [point.longitude, point.latitude],
|
|
||||||
zoom: Math.min(state.map.getZoom() + 2, 20),
|
|
||||||
duration: 300
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
const marker = new maplibregl.Marker({element})
|
state.map.addSource(state.clusterSourceId, sourceOptions)
|
||||||
.setLngLat([point.longitude, point.latitude])
|
state.map.addLayer({
|
||||||
.addTo(state.map)
|
id: state.clusterCircleId,
|
||||||
|
type: "circle",
|
||||||
|
source: state.clusterSourceId,
|
||||||
|
filter: ["has", "point_count"],
|
||||||
|
paint: {
|
||||||
|
"circle-color": [
|
||||||
|
"case",
|
||||||
|
[">", ["coalesce", ["get", "urgent_count"], 0], 0],
|
||||||
|
"#c2412d",
|
||||||
|
"#087f5b"
|
||||||
|
],
|
||||||
|
"circle-radius": [
|
||||||
|
"step",
|
||||||
|
["coalesce", ["get", "total_count"], ["get", "point_count"]],
|
||||||
|
22,
|
||||||
|
100,
|
||||||
|
25,
|
||||||
|
1_000,
|
||||||
|
28,
|
||||||
|
10_000,
|
||||||
|
31,
|
||||||
|
100_000,
|
||||||
|
34
|
||||||
|
],
|
||||||
|
"circle-stroke-color": "#ffffff",
|
||||||
|
"circle-stroke-width": 3,
|
||||||
|
"circle-opacity": 0.96
|
||||||
|
}
|
||||||
|
})
|
||||||
|
state.map.addLayer({
|
||||||
|
id: state.serverClusterCircleId,
|
||||||
|
type: "circle",
|
||||||
|
source: state.clusterSourceId,
|
||||||
|
filter: [
|
||||||
|
"all",
|
||||||
|
["!", ["has", "point_count"]],
|
||||||
|
["==", ["get", "item_type"], "cluster"]
|
||||||
|
],
|
||||||
|
paint: {
|
||||||
|
"circle-color": [
|
||||||
|
"case",
|
||||||
|
[">", ["coalesce", ["get", "urgent_weight"], 0], 0],
|
||||||
|
"#c2412d",
|
||||||
|
"#087f5b"
|
||||||
|
],
|
||||||
|
"circle-radius": [
|
||||||
|
"step",
|
||||||
|
["get", "weight"],
|
||||||
|
22,
|
||||||
|
100,
|
||||||
|
25,
|
||||||
|
1_000,
|
||||||
|
28,
|
||||||
|
10_000,
|
||||||
|
31,
|
||||||
|
100_000,
|
||||||
|
34
|
||||||
|
],
|
||||||
|
"circle-stroke-color": "#ffffff",
|
||||||
|
"circle-stroke-width": 3,
|
||||||
|
"circle-opacity": 0.96
|
||||||
|
}
|
||||||
|
})
|
||||||
|
state.map.addLayer({
|
||||||
|
id: state.pointCircleId,
|
||||||
|
type: "circle",
|
||||||
|
source: state.clusterSourceId,
|
||||||
|
filter: [
|
||||||
|
"all",
|
||||||
|
["!", ["has", "point_count"]],
|
||||||
|
["!=", ["get", "item_type"], "cluster"]
|
||||||
|
],
|
||||||
|
paint: {
|
||||||
|
"circle-color": [
|
||||||
|
"case",
|
||||||
|
["==", ["get", "item_type"], "live"],
|
||||||
|
"#2563eb",
|
||||||
|
["==", ["get", "exact"], true],
|
||||||
|
"#d6573b",
|
||||||
|
"#278467"
|
||||||
|
],
|
||||||
|
"circle-radius": 9,
|
||||||
|
"circle-stroke-color": "#ffffff",
|
||||||
|
"circle-stroke-width": 3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
state.map.addLayer({
|
||||||
|
id: state.pointSelectedId,
|
||||||
|
type: "circle",
|
||||||
|
source: state.clusterSourceId,
|
||||||
|
filter: ["==", ["get", "id"], state.selectedItemId || ""],
|
||||||
|
paint: {
|
||||||
|
"circle-color": "rgba(0,0,0,0)",
|
||||||
|
"circle-radius": 15,
|
||||||
|
"circle-stroke-color": "#111827",
|
||||||
|
"circle-stroke-width": 3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
state.markers.push(marker)
|
const interactiveLayers = [
|
||||||
})
|
state.clusterCircleId,
|
||||||
|
state.serverClusterCircleId,
|
||||||
|
state.pointCircleId
|
||||||
|
]
|
||||||
|
|
||||||
|
interactiveLayers.forEach(layerId => {
|
||||||
|
state.map.on("mouseenter", layerId, () => {
|
||||||
|
state.map.getCanvas().style.cursor = "pointer"
|
||||||
|
})
|
||||||
|
state.map.on("mouseleave", layerId, () => {
|
||||||
|
state.map.getCanvas().style.cursor = ""
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
state.map.on("click", state.clusterCircleId, event => {
|
||||||
|
const feature = event.features?.[0]
|
||||||
|
if (feature) state.expandNativeCluster(feature)
|
||||||
|
})
|
||||||
|
|
||||||
|
state.map.on("click", state.serverClusterCircleId, event => {
|
||||||
|
const feature = event.features?.[0]
|
||||||
|
if (feature) state.expandServerCluster(feature)
|
||||||
|
})
|
||||||
|
|
||||||
|
state.map.on("click", state.pointCircleId, event => {
|
||||||
|
const feature = event.features?.[0]
|
||||||
|
const properties = feature?.properties
|
||||||
|
if (!feature || !properties) return
|
||||||
|
|
||||||
|
if (properties.id) state.selectRequest(properties.id)
|
||||||
|
|
||||||
|
new maplibregl.Popup({offset: 18})
|
||||||
|
.setLngLat(feature.geometry.coordinates)
|
||||||
|
.setDOMContent(state.popupContent(properties))
|
||||||
|
.addTo(state.map)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.element.dataset.autoFit !== "false") state.fitMarkers()
|
if (state.element.dataset.autoFit !== "false") state.fitMarkers()
|
||||||
}
|
}
|
||||||
|
|
@ -752,7 +1037,6 @@ const createAidMap = element => {
|
||||||
|
|
||||||
state.onMoveEnd = () => {
|
state.onMoveEnd = () => {
|
||||||
if (!state.initializedViewport || state.element.dataset.discoveryMap !== "true") return
|
if (!state.initializedViewport || state.element.dataset.discoveryMap !== "true") return
|
||||||
state.renderMarkers()
|
|
||||||
const viewport = mapViewport(state.map)
|
const viewport = mapViewport(state.map)
|
||||||
if (!viewport) return
|
if (!viewport) return
|
||||||
|
|
||||||
|
|
@ -764,11 +1048,23 @@ const createAidMap = element => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.onIdle = () => {
|
||||||
|
state.markReady()
|
||||||
|
|
||||||
|
if (state.pendingMarkerRender) {
|
||||||
|
state.renderMarkers()
|
||||||
|
if (state.pendingMarkerRender) return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.syncVisibleAreas()
|
||||||
|
state.syncClusterMarkers()
|
||||||
|
}
|
||||||
|
|
||||||
state.onRequestHighlight = event => state.highlightRequest(event.detail?.id)
|
state.onRequestHighlight = event => state.highlightRequest(event.detail?.id)
|
||||||
|
|
||||||
state.map.on("dataloading", state.markLoading)
|
state.map.on("dataloading", state.markLoading)
|
||||||
state.map.on("load", state.onLoad)
|
state.map.on("load", state.onLoad)
|
||||||
state.map.on("idle", state.markReady)
|
state.map.on("idle", state.onIdle)
|
||||||
state.map.on("moveend", state.onMoveEnd)
|
state.map.on("moveend", state.onMoveEnd)
|
||||||
window.addEventListener("wnh:request-highlight", state.onRequestHighlight)
|
window.addEventListener("wnh:request-highlight", state.onRequestHighlight)
|
||||||
if ("ResizeObserver" in window) {
|
if ("ResizeObserver" in window) {
|
||||||
|
|
@ -785,7 +1081,7 @@ const createAidMap = element => {
|
||||||
state.resizeObserver?.disconnect()
|
state.resizeObserver?.disconnect()
|
||||||
state.map?.off("dataloading", state.markLoading)
|
state.map?.off("dataloading", state.markLoading)
|
||||||
state.map?.off("load", state.onLoad)
|
state.map?.off("load", state.onLoad)
|
||||||
state.map?.off("idle", state.markReady)
|
state.map?.off("idle", state.onIdle)
|
||||||
state.map?.off("moveend", state.onMoveEnd)
|
state.map?.off("moveend", state.onMoveEnd)
|
||||||
window.removeEventListener("wnh:request-highlight", state.onRequestHighlight)
|
window.removeEventListener("wnh:request-highlight", state.onRequestHighlight)
|
||||||
state.map?.remove()
|
state.map?.remove()
|
||||||
|
|
|
||||||
59
assets/js/map_cluster_features.mjs
Normal file
59
assets/js/map_cluster_features.mjs
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
const finiteCount = (value, fallback) => {
|
||||||
|
const count = Number(value)
|
||||||
|
return Number.isFinite(count) && count >= 0 ? count : fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
export const clusterSizeClass = count => {
|
||||||
|
if (count >= 100_000) return "is-xxl"
|
||||||
|
if (count >= 10_000) return "is-xl"
|
||||||
|
if (count >= 1_000) return "is-lg"
|
||||||
|
return "is-md"
|
||||||
|
}
|
||||||
|
|
||||||
|
export const clusterCountLabel = (count, locale = "en") => {
|
||||||
|
const value = finiteCount(count, 0)
|
||||||
|
|
||||||
|
if (value < 1_000) return new Intl.NumberFormat(locale).format(value)
|
||||||
|
|
||||||
|
return new Intl.NumberFormat(locale, {
|
||||||
|
notation: "compact",
|
||||||
|
maximumFractionDigits: value < 10_000 ? 1 : 0
|
||||||
|
}).format(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const clusterExpansionTarget = (currentZoom, requestedZoom, maximumZoom = 22) => {
|
||||||
|
const current = finiteCount(currentZoom, 0)
|
||||||
|
const requested = finiteCount(requestedZoom, current + 1)
|
||||||
|
const nearestIntegerZoom = Math.round(current)
|
||||||
|
const normalizedCurrent =
|
||||||
|
Math.abs(current - nearestIntegerZoom) < 0.001 ? nearestIntegerZoom : current
|
||||||
|
const nextIntegerZoom = Math.floor(normalizedCurrent) + 1
|
||||||
|
|
||||||
|
return Math.min(maximumZoom, Math.max(nextIntegerZoom, requested))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pointFeatureCollection = points => ({
|
||||||
|
type: "FeatureCollection",
|
||||||
|
features: points.map(point => ({
|
||||||
|
type: "Feature",
|
||||||
|
id: point.id,
|
||||||
|
properties: {
|
||||||
|
id: point.id,
|
||||||
|
item_type: point.type || "request",
|
||||||
|
title: point.title || "",
|
||||||
|
location: point.location || "",
|
||||||
|
exact: point.exact === true,
|
||||||
|
radius_meters: Number.isFinite(point.radius_meters) ? point.radius_meters : 0,
|
||||||
|
weight: finiteCount(point.count, 1),
|
||||||
|
urgent_weight: finiteCount(point.urgent_count, 0),
|
||||||
|
server_cluster_id: point.cluster_id || "",
|
||||||
|
parent_cluster_id: point.parent_cluster_id || "",
|
||||||
|
hierarchy_level: finiteCount(point.hierarchy_level, 0),
|
||||||
|
expansion_zoom: finiteCount(point.expansion_zoom, 22)
|
||||||
|
},
|
||||||
|
geometry: {
|
||||||
|
type: "Point",
|
||||||
|
coordinates: [Number(point.longitude), Number(point.latitude)]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})
|
||||||
123
assets/js/map_cluster_features.test.mjs
Normal file
123
assets/js/map_cluster_features.test.mjs
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
import assert from "node:assert/strict"
|
||||||
|
import test from "node:test"
|
||||||
|
|
||||||
|
import {Supercluster} from "@maplibre/geojson-vt"
|
||||||
|
import {
|
||||||
|
clusterCountLabel,
|
||||||
|
clusterExpansionTarget,
|
||||||
|
clusterSizeClass,
|
||||||
|
pointFeatureCollection
|
||||||
|
} from "./map_cluster_features.mjs"
|
||||||
|
|
||||||
|
const buildIndex = points => {
|
||||||
|
const index = new Supercluster({
|
||||||
|
radius: 64,
|
||||||
|
maxZoom: 21,
|
||||||
|
minPoints: 2,
|
||||||
|
map: properties => ({
|
||||||
|
total_count: properties.weight,
|
||||||
|
urgent_count: properties.urgent_weight
|
||||||
|
}),
|
||||||
|
reduce: (accumulated, properties) => {
|
||||||
|
accumulated.total_count += properties.total_count
|
||||||
|
accumulated.urgent_count += properties.urgent_count
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
index.load(pointFeatureCollection(points).features)
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
test("weighted server nodes preserve the represented record total", () => {
|
||||||
|
const index = buildIndex([
|
||||||
|
{id: "request:4:1:1", type: "cluster", longitude: 30.50, latitude: 50.45, count: 700},
|
||||||
|
{
|
||||||
|
id: "request:4:1:2",
|
||||||
|
type: "cluster",
|
||||||
|
longitude: 30.51,
|
||||||
|
latitude: 50.46,
|
||||||
|
count: 300,
|
||||||
|
urgent_count: 10
|
||||||
|
},
|
||||||
|
{id: "one", type: "request", longitude: -74.0, latitude: 40.7}
|
||||||
|
])
|
||||||
|
|
||||||
|
const world = index.getClusters([-180, -85, 180, 85], 0)
|
||||||
|
const represented = world.reduce(
|
||||||
|
(sum, feature) => sum + (feature.properties.total_count || feature.properties.weight),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
const urgent = world.reduce(
|
||||||
|
(sum, feature) => sum + (feature.properties.urgent_count || feature.properties.urgent_weight),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.equal(represented, 1_001)
|
||||||
|
assert.equal(urgent, 10)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("server hierarchy metadata survives GeoJSON conversion without becoming a native cluster", () => {
|
||||||
|
const feature = pointFeatureCollection([
|
||||||
|
{
|
||||||
|
id: "request:11:1197:1378",
|
||||||
|
type: "cluster",
|
||||||
|
cluster_id: "request:11:1197:1378",
|
||||||
|
parent_cluster_id: "request:10:598:689",
|
||||||
|
hierarchy_level: 11,
|
||||||
|
expansion_zoom: 13,
|
||||||
|
longitude: 30.52,
|
||||||
|
latitude: 50.45,
|
||||||
|
count: 27
|
||||||
|
}
|
||||||
|
]).features[0]
|
||||||
|
|
||||||
|
assert.equal(feature.properties.server_cluster_id, "request:11:1197:1378")
|
||||||
|
assert.equal(feature.properties.parent_cluster_id, "request:10:598:689")
|
||||||
|
assert.equal(feature.properties.hierarchy_level, 11)
|
||||||
|
assert.equal(feature.properties.expansion_zoom, 13)
|
||||||
|
assert.equal(feature.properties.weight, 27)
|
||||||
|
assert.equal("point_count" in feature.properties, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("native clusters expose an expansion zoom and eventually split unique coordinates", () => {
|
||||||
|
const index = buildIndex([
|
||||||
|
{id: "a", longitude: 30.52340, latitude: 50.45010},
|
||||||
|
{id: "b", longitude: 30.52341, latitude: 50.45011},
|
||||||
|
{id: "c", longitude: 30.60, latitude: 50.50}
|
||||||
|
])
|
||||||
|
|
||||||
|
const world = index.getClusters([-180, -85, 180, 85], 0)
|
||||||
|
const cluster = world.find(feature => feature.properties.cluster)
|
||||||
|
|
||||||
|
assert.ok(cluster)
|
||||||
|
assert.ok(index.getClusterExpansionZoom(cluster.properties.cluster_id) > 0)
|
||||||
|
assert.equal(
|
||||||
|
index.getClusters([30.5, 50.4, 30.7, 50.6], 22)
|
||||||
|
.filter(feature => !feature.properties.cluster)
|
||||||
|
.length,
|
||||||
|
3
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cluster size classes remain stable for accessible count buttons", () => {
|
||||||
|
assert.equal(clusterSizeClass(999), "is-md")
|
||||||
|
assert.equal(clusterSizeClass(1_000), "is-lg")
|
||||||
|
assert.equal(clusterSizeClass(10_000), "is-xl")
|
||||||
|
assert.equal(clusterSizeClass(100_000), "is-xxl")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("large visual counts are compact while exact values remain available to accessibility text", () => {
|
||||||
|
assert.equal(clusterCountLabel(999, "en"), "999")
|
||||||
|
assert.equal(clusterCountLabel(1_250, "en"), "1.3K")
|
||||||
|
assert.equal(clusterCountLabel(48_533, "en"), "49K")
|
||||||
|
assert.equal(clusterCountLabel(1_000_000, "en"), "1M")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cluster expansion always advances at least one integer zoom level", () => {
|
||||||
|
assert.equal(clusterExpansionTarget(9, 9), 10)
|
||||||
|
assert.equal(clusterExpansionTarget(8.999_999_096_835_52, 9), 10)
|
||||||
|
assert.equal(clusterExpansionTarget(10.999_994_193_019_71, 11), 12)
|
||||||
|
assert.equal(clusterExpansionTarget(9.6, 10), 10)
|
||||||
|
assert.equal(clusterExpansionTarget(9.6, 13), 13)
|
||||||
|
assert.equal(clusterExpansionTarget(21.9, 24), 22)
|
||||||
|
})
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
const clusterCount = point => {
|
|
||||||
const count = Number(point?.count)
|
|
||||||
return Number.isFinite(count) && count > 0 ? count : 1
|
|
||||||
}
|
|
||||||
|
|
||||||
const urgentCount = point => {
|
|
||||||
const count = Number(point?.urgent_count)
|
|
||||||
return Number.isFinite(count) && count > 0 ? count : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
export const clusterDiameterPixels = count => {
|
|
||||||
if (count >= 100_000) return 60
|
|
||||||
if (count >= 10_000) return 56
|
|
||||||
if (count >= 1_000) return 52
|
|
||||||
return 44
|
|
||||||
}
|
|
||||||
|
|
||||||
export const clusterSizeClass = count => {
|
|
||||||
if (count >= 100_000) return "is-xxl"
|
|
||||||
if (count >= 10_000) return "is-xl"
|
|
||||||
if (count >= 1_000) return "is-lg"
|
|
||||||
return "is-md"
|
|
||||||
}
|
|
||||||
|
|
||||||
const mergeDistance = (left, right, gap) =>
|
|
||||||
(clusterDiameterPixels(left.count) + clusterDiameterPixels(right.count)) / 2 + gap
|
|
||||||
|
|
||||||
const coordinatesFromPixel = (map, pixel) => {
|
|
||||||
const coordinates = map.unproject([pixel.x, pixel.y])
|
|
||||||
|
|
||||||
return {
|
|
||||||
longitude: Number(coordinates.lng ?? coordinates[0]),
|
|
||||||
latitude: Number(coordinates.lat ?? coordinates[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const finiteCoordinate = value => {
|
|
||||||
const coordinate = Number(value)
|
|
||||||
return Number.isFinite(coordinate) ? coordinate : null
|
|
||||||
}
|
|
||||||
|
|
||||||
const pointBounds = point => {
|
|
||||||
const longitude = finiteCoordinate(point?.longitude)
|
|
||||||
const latitude = finiteCoordinate(point?.latitude)
|
|
||||||
const source = point?.bounds || {}
|
|
||||||
const west = finiteCoordinate(source.west) ?? longitude
|
|
||||||
const south = finiteCoordinate(source.south) ?? latitude
|
|
||||||
const east = finiteCoordinate(source.east) ?? longitude
|
|
||||||
const north = finiteCoordinate(source.north) ?? latitude
|
|
||||||
|
|
||||||
if ([west, south, east, north].some(value => value === null)) return null
|
|
||||||
|
|
||||||
return {
|
|
||||||
west: Math.min(west, east),
|
|
||||||
south: Math.min(south, north),
|
|
||||||
east: Math.max(west, east),
|
|
||||||
north: Math.max(south, north)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupBounds = points => {
|
|
||||||
const bounds = points.map(pointBounds).filter(Boolean)
|
|
||||||
if (bounds.length === 0) return null
|
|
||||||
|
|
||||||
return bounds.reduce(
|
|
||||||
(result, current) => ({
|
|
||||||
west: Math.min(result.west, current.west),
|
|
||||||
south: Math.min(result.south, current.south),
|
|
||||||
east: Math.max(result.east, current.east),
|
|
||||||
north: Math.max(result.north, current.north)
|
|
||||||
}),
|
|
||||||
bounds[0]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const nearbyMapPointGroups = (map, points, options = {}) => {
|
|
||||||
const gap = Number.isFinite(options.gap) ? Math.max(options.gap, 0) : 8
|
|
||||||
|
|
||||||
const groups = points.map(point => {
|
|
||||||
const pixel = map.project([point.longitude, point.latitude])
|
|
||||||
|
|
||||||
return {
|
|
||||||
points: [point],
|
|
||||||
x: pixel.x,
|
|
||||||
y: pixel.y,
|
|
||||||
count: clusterCount(point),
|
|
||||||
urgent_count: urgentCount(point)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let merged = true
|
|
||||||
|
|
||||||
while (merged) {
|
|
||||||
merged = false
|
|
||||||
|
|
||||||
outer:
|
|
||||||
for (let leftIndex = 0; leftIndex < groups.length; leftIndex += 1) {
|
|
||||||
for (let rightIndex = leftIndex + 1; rightIndex < groups.length; rightIndex += 1) {
|
|
||||||
const left = groups[leftIndex]
|
|
||||||
const right = groups[rightIndex]
|
|
||||||
const distance = Math.hypot(left.x - right.x, left.y - right.y)
|
|
||||||
|
|
||||||
if (distance >= mergeDistance(left, right, gap)) continue
|
|
||||||
|
|
||||||
const count = left.count + right.count
|
|
||||||
left.x = (left.x * left.count + right.x * right.count) / count
|
|
||||||
left.y = (left.y * left.count + right.y * right.count) / count
|
|
||||||
left.count = count
|
|
||||||
left.urgent_count += right.urgent_count
|
|
||||||
left.points.push(...right.points)
|
|
||||||
groups.splice(rightIndex, 1)
|
|
||||||
merged = true
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups
|
|
||||||
}
|
|
||||||
|
|
||||||
const visualCluster = (map, group) => {
|
|
||||||
const coordinates = coordinatesFromPixel(map, group)
|
|
||||||
const firstId = group.points[0]?.id || "anonymous"
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: "cluster",
|
|
||||||
id: `visual-cluster-${group.points.length}-${firstId}`,
|
|
||||||
count: group.count,
|
|
||||||
urgent_count: group.urgent_count,
|
|
||||||
longitude: coordinates.longitude,
|
|
||||||
latitude: coordinates.latitude,
|
|
||||||
bounds: groupBounds(group.points)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const mergeNearbyMapClusters = (map, points, options = {}) =>
|
|
||||||
nearbyMapPointGroups(map, points, options).map(group => visualCluster(map, group))
|
|
||||||
|
|
||||||
export const mergeNearbyMapPoints = (map, points, options = {}) => {
|
|
||||||
return nearbyMapPointGroups(map, points, options).map(group => {
|
|
||||||
const point = group.points[0]
|
|
||||||
|
|
||||||
if (group.points.length === 1 && point?.type !== "cluster") return point
|
|
||||||
|
|
||||||
return visualCluster(map, group)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
import assert from "node:assert/strict"
|
|
||||||
import test from "node:test"
|
|
||||||
|
|
||||||
import {
|
|
||||||
clusterDiameterPixels,
|
|
||||||
clusterSizeClass,
|
|
||||||
mergeNearbyMapClusters,
|
|
||||||
mergeNearbyMapPoints
|
|
||||||
} from "./map_cluster_points.mjs"
|
|
||||||
|
|
||||||
const flatMap = scale => ({
|
|
||||||
project: ([longitude, latitude]) => ({x: longitude * scale, y: latitude * scale}),
|
|
||||||
unproject: ([x, y]) => ({lng: x / scale, lat: y / scale})
|
|
||||||
})
|
|
||||||
|
|
||||||
test("merges visually overlapping clusters and preserves their total", () => {
|
|
||||||
const points = [
|
|
||||||
{
|
|
||||||
id: "a",
|
|
||||||
type: "cluster",
|
|
||||||
count: 100,
|
|
||||||
urgent_count: 2,
|
|
||||||
longitude: 0,
|
|
||||||
latitude: 0,
|
|
||||||
bounds: {west: -5, south: -2, east: 5, north: 2}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "b",
|
|
||||||
type: "cluster",
|
|
||||||
count: 50,
|
|
||||||
urgent_count: 1,
|
|
||||||
longitude: 30,
|
|
||||||
latitude: 0,
|
|
||||||
bounds: {west: 25, south: -3, east: 35, north: 4}
|
|
||||||
},
|
|
||||||
{id: "c", type: "cluster", count: 7, urgent_count: 0, longitude: 140, latitude: 0}
|
|
||||||
]
|
|
||||||
|
|
||||||
const result = mergeNearbyMapClusters(flatMap(1), points)
|
|
||||||
|
|
||||||
assert.equal(result.length, 2)
|
|
||||||
assert.equal(result.reduce((total, cluster) => total + cluster.count, 0), 157)
|
|
||||||
|
|
||||||
const merged = result.find(cluster => cluster.count === 150)
|
|
||||||
assert.equal(merged.urgent_count, 3)
|
|
||||||
assert.equal(merged.longitude, 10)
|
|
||||||
assert.equal(merged.latitude, 0)
|
|
||||||
assert.deepEqual(merged.bounds, {west: -5, south: -3, east: 35, north: 4})
|
|
||||||
})
|
|
||||||
|
|
||||||
test("splits the same clusters again at a closer zoom", () => {
|
|
||||||
const points = [
|
|
||||||
{id: "a", type: "cluster", count: 20, longitude: 0, latitude: 0},
|
|
||||||
{id: "b", type: "cluster", count: 30, longitude: 30, latitude: 0}
|
|
||||||
]
|
|
||||||
|
|
||||||
assert.equal(mergeNearbyMapClusters(flatMap(1), points).length, 1)
|
|
||||||
assert.equal(mergeNearbyMapClusters(flatMap(3), points).length, 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("merges a singleton into an overlapping cluster at a distant zoom", () => {
|
|
||||||
const points = [
|
|
||||||
{id: "cluster", type: "cluster", count: 351, longitude: 0, latitude: 0},
|
|
||||||
{id: "request", type: "request", longitude: 28, latitude: 0, exact: true}
|
|
||||||
]
|
|
||||||
|
|
||||||
const result = mergeNearbyMapPoints(flatMap(1), points)
|
|
||||||
|
|
||||||
assert.equal(result.length, 1)
|
|
||||||
assert.equal(result[0].type, "cluster")
|
|
||||||
assert.equal(result[0].count, 352)
|
|
||||||
assert.deepEqual(result[0].bounds, {west: 0, south: 0, east: 28, north: 0})
|
|
||||||
})
|
|
||||||
|
|
||||||
test("keeps separated singleton points interactive at a closer zoom", () => {
|
|
||||||
const points = [
|
|
||||||
{id: "left", type: "request", longitude: 0, latitude: 0, exact: true},
|
|
||||||
{
|
|
||||||
id: "right",
|
|
||||||
type: "request",
|
|
||||||
longitude: 30,
|
|
||||||
latitude: 0,
|
|
||||||
radius_meters: 1_000
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const result = mergeNearbyMapPoints(flatMap(3), points)
|
|
||||||
|
|
||||||
assert.deepEqual(result, points)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("uses larger non-overlapping markers for larger totals", () => {
|
|
||||||
assert.equal(clusterDiameterPixels(999), 44)
|
|
||||||
assert.equal(clusterDiameterPixels(1_000), 52)
|
|
||||||
assert.equal(clusterDiameterPixels(10_000), 56)
|
|
||||||
assert.equal(clusterDiameterPixels(100_000), 60)
|
|
||||||
assert.equal(clusterSizeClass(999), "is-md")
|
|
||||||
assert.equal(clusterSizeClass(1_000), "is-lg")
|
|
||||||
assert.equal(clusterSizeClass(10_000), "is-xl")
|
|
||||||
assert.equal(clusterSizeClass(100_000), "is-xxl")
|
|
||||||
})
|
|
||||||
|
|
@ -11,7 +11,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
@default_rows 1_000_000
|
@default_rows 1_000_000
|
||||||
@synthetic_users 1_000
|
@synthetic_users 1_000
|
||||||
@viewer_email "scale-viewer@example.invalid"
|
@viewer_email "scale-viewer@example.invalid"
|
||||||
@fixture_version 7
|
@fixture_version 8
|
||||||
@request_open_modulus 1
|
@request_open_modulus 1
|
||||||
@activity_open_modulus 1
|
@activity_open_modulus 1
|
||||||
@places [
|
@places [
|
||||||
|
|
@ -425,10 +425,11 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
'Synthetic data only; no real-world action is requested.',
|
'Synthetic data only; no real-world action is requested.',
|
||||||
jsonb_build_object(
|
jsonb_build_object(
|
||||||
'scale_fixture', true,
|
'scale_fixture', true,
|
||||||
'scale_fixture_version', $7::integer
|
'scale_fixture_version', $7::integer,
|
||||||
|
'scale_place', place.name,
|
||||||
|
'scale_location_index', local.local_index
|
||||||
),
|
),
|
||||||
place.name || ' synthetic area ' ||
|
place.name || ' synthetic location ' || (local.local_index + 1),
|
||||||
((variation.category_key + variation.time_key) % 100 + 1),
|
|
||||||
CASE WHEN variation.visibility_key % 20 = 0 THEN NULL
|
CASE WHEN variation.visibility_key % 20 = 0 THEN NULL
|
||||||
ELSE ST_SetSRID(
|
ELSE ST_SetSRID(
|
||||||
ST_MakePoint(coordinates.longitude, coordinates.latitude),
|
ST_MakePoint(coordinates.longitude, coordinates.latitude),
|
||||||
|
|
@ -469,8 +470,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
FROM generate_series(1, $1) AS value
|
FROM generate_series(1, $1) AS value
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
md5('wnh-scale-request-v5-' || value) AS fixture_hash,
|
md5('wnh-scale-request-v8-' || value) AS fixture_hash
|
||||||
md5('wnh-scale-request-geography-v5-' || value) AS geography_hash
|
|
||||||
) AS fixture
|
) AS fixture
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
|
|
@ -482,52 +482,56 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
AS time_key,
|
AS time_key,
|
||||||
('x' || substr(fixture.fixture_hash, 25, 8))::bit(32)::bigint
|
('x' || substr(fixture.fixture_hash, 25, 8))::bit(32)::bigint
|
||||||
AS category_key,
|
AS category_key,
|
||||||
('x' || substr(fixture.geography_hash, 1, 8))::bit(32)::bigint
|
('x' || substr(md5('wnh-scale-request-owner-v8-' || value), 1, 8))
|
||||||
AS place_key,
|
::bit(32)::bigint AS owner_key
|
||||||
('x' || substr(fixture.geography_hash, 9, 8))::bit(32)::bigint
|
|
||||||
AS angle_key,
|
|
||||||
('x' || substr(fixture.geography_hash, 17, 8))::bit(32)::bigint
|
|
||||||
AS distance_key,
|
|
||||||
('x' || substr(fixture.geography_hash, 25, 8))::bit(32)::bigint
|
|
||||||
AS owner_key
|
|
||||||
) AS variation
|
) AS variation
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT name, longitude, latitude
|
SELECT name, longitude, latitude, position
|
||||||
FROM unnest(
|
FROM unnest(
|
||||||
$4::text[],
|
$4::text[],
|
||||||
$5::double precision[],
|
$5::double precision[],
|
||||||
$6::double precision[]
|
$6::double precision[]
|
||||||
) WITH ORDINALITY AS places(name, longitude, latitude, position)
|
) WITH ORDINALITY AS places(name, longitude, latitude, position)
|
||||||
WHERE places.position = variation.place_key % cardinality($4::text[]) + 1
|
WHERE places.position = ((value - 1) % cardinality($4::text[])) + 1
|
||||||
) AS place
|
) AS place
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
2 * pi() *
|
(value - 1) / cardinality($4::text[]) AS local_index
|
||||||
((variation.angle_key % 1000003)::double precision / 1000003.0) AS angle,
|
) AS local
|
||||||
sqrt(
|
|
||||||
((variation.distance_key / 20 % 1000003)::double precision + 1) /
|
|
||||||
1000004.0
|
|
||||||
) *
|
|
||||||
CASE WHEN variation.distance_key % 20 < 12 THEN 15.0
|
|
||||||
WHEN variation.distance_key % 20 < 18 THEN 60.0
|
|
||||||
ELSE 220.0
|
|
||||||
END AS distance_km
|
|
||||||
) AS geography
|
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
place.latitude +
|
(
|
||||||
geography.distance_km / 111.32 * sin(geography.angle) AS raw_latitude,
|
((local.local_index % 256) * 73 +
|
||||||
|
((local.local_index / 256) % 256) * 16) % 256
|
||||||
|
)::double precision AS grid_x,
|
||||||
|
(
|
||||||
|
(((local.local_index / 256) % 256) * 53 +
|
||||||
|
(local.local_index % 256) * 29) % 256
|
||||||
|
)::double precision AS grid_y
|
||||||
|
) AS grid
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
(grid.grid_x / 255.0 - 0.5) * 12.0 AS east_km,
|
||||||
|
(grid.grid_y / 255.0 - 0.5) * 12.0 AS north_km,
|
||||||
|
radians((place.position * 137.50776405) % 360.0) AS rotation
|
||||||
|
) AS local_offset
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
local_offset.east_km * cos(local_offset.rotation) -
|
||||||
|
local_offset.north_km * sin(local_offset.rotation) AS east_km,
|
||||||
|
local_offset.east_km * sin(local_offset.rotation) +
|
||||||
|
local_offset.north_km * cos(local_offset.rotation) AS north_km
|
||||||
|
) AS rotated_offset
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
greatest(
|
||||||
|
-84.0,
|
||||||
|
least(84.0, place.latitude + rotated_offset.north_km / 111.32)
|
||||||
|
) AS latitude,
|
||||||
place.longitude +
|
place.longitude +
|
||||||
geography.distance_km /
|
rotated_offset.east_km /
|
||||||
(111.32 * greatest(abs(cos(radians(place.latitude))), 0.2)) *
|
(111.32 * greatest(abs(cos(radians(place.latitude))), 0.2))
|
||||||
cos(geography.angle) AS raw_longitude
|
AS longitude
|
||||||
) AS raw_coordinates
|
|
||||||
CROSS JOIN LATERAL (
|
|
||||||
SELECT
|
|
||||||
greatest(-84.0, least(84.0, raw_coordinates.raw_latitude)) AS latitude,
|
|
||||||
(raw_coordinates.raw_longitude + 180.0) -
|
|
||||||
360.0 * floor((raw_coordinates.raw_longitude + 180.0) / 360.0) -
|
|
||||||
180.0 AS longitude
|
|
||||||
) AS coordinates
|
) AS coordinates
|
||||||
ON CONFLICT (id) DO UPDATE SET
|
ON CONFLICT (id) DO UPDATE SET
|
||||||
title = EXCLUDED.title,
|
title = EXCLUDED.title,
|
||||||
|
|
@ -578,10 +582,11 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
'Synthetic scale activity used to test geographic discovery, privacy, and UI.',
|
'Synthetic scale activity used to test geographic discovery, privacy, and UI.',
|
||||||
jsonb_build_object(
|
jsonb_build_object(
|
||||||
'scale_fixture', true,
|
'scale_fixture', true,
|
||||||
'scale_fixture_version', $7::integer
|
'scale_fixture_version', $7::integer,
|
||||||
|
'scale_place', place.name,
|
||||||
|
'scale_location_index', local.local_index
|
||||||
),
|
),
|
||||||
place.name || ' synthetic area ' ||
|
place.name || ' synthetic location ' || (local.local_index + 1),
|
||||||
((variation.category_key + variation.time_key) % 100 + 1),
|
|
||||||
ST_SetSRID(
|
ST_SetSRID(
|
||||||
ST_MakePoint(coordinates.longitude, coordinates.latitude),
|
ST_MakePoint(coordinates.longitude, coordinates.latitude),
|
||||||
4326
|
4326
|
||||||
|
|
@ -615,8 +620,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
FROM generate_series(1, $1) AS value
|
FROM generate_series(1, $1) AS value
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
md5('wnh-scale-activity-v5-' || value) AS fixture_hash,
|
md5('wnh-scale-activity-v8-' || value) AS fixture_hash
|
||||||
md5('wnh-scale-activity-geography-v5-' || value) AS geography_hash
|
|
||||||
) AS fixture
|
) AS fixture
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
|
|
@ -628,52 +632,56 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
AS time_key,
|
AS time_key,
|
||||||
('x' || substr(fixture.fixture_hash, 25, 8))::bit(32)::bigint
|
('x' || substr(fixture.fixture_hash, 25, 8))::bit(32)::bigint
|
||||||
AS category_key,
|
AS category_key,
|
||||||
('x' || substr(fixture.geography_hash, 1, 8))::bit(32)::bigint
|
('x' || substr(md5('wnh-scale-activity-owner-v8-' || value), 1, 8))
|
||||||
AS place_key,
|
::bit(32)::bigint AS owner_key
|
||||||
('x' || substr(fixture.geography_hash, 9, 8))::bit(32)::bigint
|
|
||||||
AS angle_key,
|
|
||||||
('x' || substr(fixture.geography_hash, 17, 8))::bit(32)::bigint
|
|
||||||
AS distance_key,
|
|
||||||
('x' || substr(fixture.geography_hash, 25, 8))::bit(32)::bigint
|
|
||||||
AS owner_key
|
|
||||||
) AS variation
|
) AS variation
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT name, longitude, latitude
|
SELECT name, longitude, latitude, position
|
||||||
FROM unnest(
|
FROM unnest(
|
||||||
$4::text[],
|
$4::text[],
|
||||||
$5::double precision[],
|
$5::double precision[],
|
||||||
$6::double precision[]
|
$6::double precision[]
|
||||||
) WITH ORDINALITY AS places(name, longitude, latitude, position)
|
) WITH ORDINALITY AS places(name, longitude, latitude, position)
|
||||||
WHERE places.position = variation.place_key % cardinality($4::text[]) + 1
|
WHERE places.position = ((value - 1) % cardinality($4::text[])) + 1
|
||||||
) AS place
|
) AS place
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
2 * pi() *
|
(value - 1) / cardinality($4::text[]) AS local_index
|
||||||
((variation.angle_key % 1000003)::double precision / 1000003.0) AS angle,
|
) AS local
|
||||||
sqrt(
|
|
||||||
((variation.distance_key / 20 % 1000003)::double precision + 1) /
|
|
||||||
1000004.0
|
|
||||||
) *
|
|
||||||
CASE WHEN variation.distance_key % 20 < 12 THEN 15.0
|
|
||||||
WHEN variation.distance_key % 20 < 18 THEN 60.0
|
|
||||||
ELSE 220.0
|
|
||||||
END AS distance_km
|
|
||||||
) AS geography
|
|
||||||
CROSS JOIN LATERAL (
|
CROSS JOIN LATERAL (
|
||||||
SELECT
|
SELECT
|
||||||
place.latitude +
|
(
|
||||||
geography.distance_km / 111.32 * sin(geography.angle) AS raw_latitude,
|
((local.local_index % 256) * 73 +
|
||||||
|
((local.local_index / 256) % 256) * 16 + 31) % 256
|
||||||
|
)::double precision AS grid_x,
|
||||||
|
(
|
||||||
|
(((local.local_index / 256) % 256) * 53 +
|
||||||
|
(local.local_index % 256) * 29 + 47) % 256
|
||||||
|
)::double precision AS grid_y
|
||||||
|
) AS grid
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
(grid.grid_x / 255.0 - 0.5) * 12.0 AS east_km,
|
||||||
|
(grid.grid_y / 255.0 - 0.5) * 12.0 AS north_km,
|
||||||
|
radians((place.position * 137.50776405 + 19.0) % 360.0) AS rotation
|
||||||
|
) AS local_offset
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
local_offset.east_km * cos(local_offset.rotation) -
|
||||||
|
local_offset.north_km * sin(local_offset.rotation) AS east_km,
|
||||||
|
local_offset.east_km * sin(local_offset.rotation) +
|
||||||
|
local_offset.north_km * cos(local_offset.rotation) AS north_km
|
||||||
|
) AS rotated_offset
|
||||||
|
CROSS JOIN LATERAL (
|
||||||
|
SELECT
|
||||||
|
greatest(
|
||||||
|
-84.0,
|
||||||
|
least(84.0, place.latitude + rotated_offset.north_km / 111.32)
|
||||||
|
) AS latitude,
|
||||||
place.longitude +
|
place.longitude +
|
||||||
geography.distance_km /
|
rotated_offset.east_km /
|
||||||
(111.32 * greatest(abs(cos(radians(place.latitude))), 0.2)) *
|
(111.32 * greatest(abs(cos(radians(place.latitude))), 0.2))
|
||||||
cos(geography.angle) AS raw_longitude
|
AS longitude
|
||||||
) AS raw_coordinates
|
|
||||||
CROSS JOIN LATERAL (
|
|
||||||
SELECT
|
|
||||||
greatest(-84.0, least(84.0, raw_coordinates.raw_latitude)) AS latitude,
|
|
||||||
(raw_coordinates.raw_longitude + 180.0) -
|
|
||||||
360.0 * floor((raw_coordinates.raw_longitude + 180.0) / 360.0) -
|
|
||||||
180.0 AS longitude
|
|
||||||
) AS coordinates
|
) AS coordinates
|
||||||
ON CONFLICT (id) DO UPDATE SET
|
ON CONFLICT (id) DO UPDATE SET
|
||||||
title = EXCLUDED.title,
|
title = EXCLUDED.title,
|
||||||
|
|
@ -1125,7 +1133,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
|
|
||||||
defp fixture_place_count!("help_requests") do
|
defp fixture_place_count!("help_requests") do
|
||||||
scalar!("""
|
scalar!("""
|
||||||
SELECT count(DISTINCT regexp_replace(location_label, ' synthetic area [0-9]+$', ''))
|
SELECT count(DISTINCT regexp_replace(location_label, ' synthetic location [0-9]+$', ''))
|
||||||
FROM help_requests
|
FROM help_requests
|
||||||
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
||||||
""")
|
""")
|
||||||
|
|
@ -1133,7 +1141,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
|
|
||||||
defp fixture_place_count!("activities") do
|
defp fixture_place_count!("activities") do
|
||||||
scalar!("""
|
scalar!("""
|
||||||
SELECT count(DISTINCT regexp_replace(location_label, ' synthetic area [0-9]+$', ''))
|
SELECT count(DISTINCT regexp_replace(location_label, ' synthetic location [0-9]+$', ''))
|
||||||
FROM activities
|
FROM activities
|
||||||
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
||||||
""")
|
""")
|
||||||
|
|
@ -1146,7 +1154,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
SELECT count(*) AS place_rows
|
SELECT count(*) AS place_rows
|
||||||
FROM help_requests
|
FROM help_requests
|
||||||
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
||||||
GROUP BY regexp_replace(location_label, ' synthetic area [0-9]+$', '')
|
GROUP BY regexp_replace(location_label, ' synthetic location [0-9]+$', '')
|
||||||
) AS grouped_places
|
) AS grouped_places
|
||||||
""")
|
""")
|
||||||
end
|
end
|
||||||
|
|
@ -1158,7 +1166,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
SELECT count(*) AS place_rows
|
SELECT count(*) AS place_rows
|
||||||
FROM activities
|
FROM activities
|
||||||
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
|
||||||
GROUP BY regexp_replace(location_label, ' synthetic area [0-9]+$', '')
|
GROUP BY regexp_replace(location_label, ' synthetic location [0-9]+$', '')
|
||||||
) AS grouped_places
|
) AS grouped_places
|
||||||
""")
|
""")
|
||||||
end
|
end
|
||||||
|
|
@ -1173,7 +1181,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
AND status = 'open'
|
AND status = 'open'
|
||||||
AND expires_at > now()
|
AND expires_at > now()
|
||||||
AND location_visibility <> 'hidden'
|
AND location_visibility <> 'hidden'
|
||||||
GROUP BY regexp_replace(location_label, ' synthetic area [0-9]+$', '')
|
GROUP BY regexp_replace(location_label, ' synthetic location [0-9]+$', '')
|
||||||
) AS grouped_places
|
) AS grouped_places
|
||||||
""")
|
""")
|
||||||
end
|
end
|
||||||
|
|
@ -1188,7 +1196,7 @@ defmodule Mix.Tasks.Wnh.ScaleFixtures do
|
||||||
AND status = 'open'
|
AND status = 'open'
|
||||||
AND starts_at > now()
|
AND starts_at > now()
|
||||||
AND location_visibility = 'approximate_public'
|
AND location_visibility = 'approximate_public'
|
||||||
GROUP BY regexp_replace(location_label, ' synthetic area [0-9]+$', '')
|
GROUP BY regexp_replace(location_label, ' synthetic location [0-9]+$', '')
|
||||||
) AS grouped_places
|
) AS grouped_places
|
||||||
""")
|
""")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ defmodule WhoNeedHelp.Activities do
|
||||||
alias WhoNeedHelp.Activities.{Activity, Message, Participant}
|
alias WhoNeedHelp.Activities.{Activity, Message, Participant}
|
||||||
alias WhoNeedHelp.Catalog
|
alias WhoNeedHelp.Catalog
|
||||||
alias WhoNeedHelp.Catalog.Category
|
alias WhoNeedHelp.Catalog.Category
|
||||||
alias WhoNeedHelp.Help.DiscoveryViewport
|
alias WhoNeedHelp.Help.{DiscoveryCluster, DiscoveryViewport}
|
||||||
alias WhoNeedHelp.Pagination
|
alias WhoNeedHelp.Pagination
|
||||||
alias WhoNeedHelp.Repo
|
alias WhoNeedHelp.Repo
|
||||||
alias WhoNeedHelp.Trust
|
alias WhoNeedHelp.Trust
|
||||||
|
|
@ -53,7 +53,9 @@ defmodule WhoNeedHelp.Activities do
|
||||||
end
|
end
|
||||||
|
|
||||||
def map_discovery_items(%Scope{user: user}, filters, %DiscoveryViewport{} = viewport) do
|
def map_discovery_items(%Scope{user: user}, filters, %DiscoveryViewport{} = viewport) do
|
||||||
cell_size = DiscoveryViewport.cluster_cell_meters(viewport)
|
level = DiscoveryCluster.level_for_zoom(viewport.zoom)
|
||||||
|
cell_size = DiscoveryCluster.cell_size_meters(level)
|
||||||
|
world_half = DiscoveryCluster.world_half_meters()
|
||||||
|
|
||||||
points =
|
points =
|
||||||
user
|
user
|
||||||
|
|
@ -87,65 +89,75 @@ defmodule WhoNeedHelp.Activities do
|
||||||
|
|
||||||
points
|
points
|
||||||
|> subquery()
|
|> subquery()
|
||||||
|> group_by(
|
|> group_by([point], [
|
||||||
[point],
|
|
||||||
fragment(
|
fragment(
|
||||||
"ST_SnapToGrid(ST_Transform(?, 3857), ?)",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
|
constant(^cell_size)
|
||||||
|
),
|
||||||
|
fragment(
|
||||||
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
)
|
])
|
||||||
|> select([point], %{
|
|> select([point], %{
|
||||||
count: count(point.id),
|
count: count(point.id),
|
||||||
activity_id: fragment("CASE WHEN count(*) = 1 THEN min(?::text) END", point.id),
|
activity_id: fragment("CASE WHEN count(*) = 1 THEN min(?::text) END", point.id),
|
||||||
title: fragment("CASE WHEN count(*) = 1 THEN min(?) END", point.title),
|
title: fragment("CASE WHEN count(*) = 1 THEN min(?) END", point.title),
|
||||||
location_label: fragment("CASE WHEN count(*) = 1 THEN min(?) END", point.location_label),
|
location_label: fragment("CASE WHEN count(*) = 1 THEN min(?) END", point.location_label),
|
||||||
longitude:
|
longitude: fragment("avg(ST_X(?))", point.public_location),
|
||||||
fragment(
|
latitude: fragment("avg(ST_Y(?))", point.public_location),
|
||||||
"CASE WHEN count(*) = 1 THEN min(ST_X(?)) ELSE avg(ST_X(?)) END",
|
|
||||||
point.public_location,
|
|
||||||
point.public_location
|
|
||||||
),
|
|
||||||
latitude:
|
|
||||||
fragment(
|
|
||||||
"CASE WHEN count(*) = 1 THEN min(ST_Y(?)) ELSE avg(ST_Y(?)) END",
|
|
||||||
point.public_location,
|
|
||||||
point.public_location
|
|
||||||
),
|
|
||||||
west: fragment("min(ST_X(?))", point.public_location),
|
west: fragment("min(ST_X(?))", point.public_location),
|
||||||
south: fragment("min(ST_Y(?))", point.public_location),
|
south: fragment("min(ST_Y(?))", point.public_location),
|
||||||
east: fragment("max(ST_X(?))", point.public_location),
|
east: fragment("max(ST_X(?))", point.public_location),
|
||||||
north: fragment("max(ST_Y(?))", point.public_location),
|
north: fragment("max(ST_Y(?))", point.public_location),
|
||||||
|
west_m: fragment("min(ST_X(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
south_m: fragment("min(ST_Y(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
east_m: fragment("max(ST_X(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
north_m: fragment("max(ST_Y(ST_Transform(?, 3857)))", point.public_location),
|
||||||
cell_x:
|
cell_x:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_X(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
),
|
),
|
||||||
cell_y:
|
cell_y:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_Y(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|> order_by(
|
|> order_by([point],
|
||||||
[point],
|
|
||||||
asc:
|
asc:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_X(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
),
|
),
|
||||||
asc:
|
asc:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_Y(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|> Enum.map(&map_discovery_item(&1, viewport.zoom))
|
|> Enum.map(&map_discovery_item(&1, level))
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_map_discovery_items(%Scope{user: user}, filters) do
|
||||||
|
user
|
||||||
|
|> open_activities_query(filters, nil)
|
||||||
|
|> where([activity], activity.location_visibility == :approximate_public)
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_my_activities(%Scope{user: user}) do
|
def list_my_activities(%Scope{user: user}) do
|
||||||
|
|
@ -968,10 +980,12 @@ defmodule WhoNeedHelp.Activities do
|
||||||
defp longitude_in_viewport?(longitude, %DiscoveryViewport{west: west, east: east}),
|
defp longitude_in_viewport?(longitude, %DiscoveryViewport{west: west, east: east}),
|
||||||
do: longitude >= west or longitude <= east
|
do: longitude >= west or longitude <= east
|
||||||
|
|
||||||
defp map_discovery_item(%{count: 1} = row, _zoom) do
|
defp map_discovery_item(%{count: 1} = row, level) do
|
||||||
%{
|
%{
|
||||||
type: "activity",
|
type: "activity",
|
||||||
id: row.activity_id,
|
id: row.activity_id,
|
||||||
|
parent_cluster_id: DiscoveryCluster.parent_id(:activity, level, row.cell_x, row.cell_y),
|
||||||
|
hierarchy_level: level,
|
||||||
title: row.title,
|
title: row.title,
|
||||||
location: row.location_label,
|
location: row.location_label,
|
||||||
latitude: row.latitude,
|
latitude: row.latitude,
|
||||||
|
|
@ -980,15 +994,24 @@ defmodule WhoNeedHelp.Activities do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp map_discovery_item(row, zoom) do
|
defp map_discovery_item(row, level) do
|
||||||
digest =
|
cluster_id = DiscoveryCluster.cluster_id(:activity, level, row.cell_x, row.cell_y)
|
||||||
:crypto.hash(:sha256, "activity:#{zoom}:#{row.cell_x}:#{row.cell_y}")
|
|
||||||
|> Base.url_encode64(padding: false)
|
|
||||||
|> binary_part(0, 16)
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
type: "cluster",
|
type: "cluster",
|
||||||
id: "activity-cluster-#{digest}",
|
id: cluster_id,
|
||||||
|
cluster_id: cluster_id,
|
||||||
|
parent_cluster_id: DiscoveryCluster.parent_id(:activity, level, row.cell_x, row.cell_y),
|
||||||
|
hierarchy_level: level,
|
||||||
|
point_count: row.count,
|
||||||
|
expansion_zoom:
|
||||||
|
DiscoveryCluster.expansion_zoom(
|
||||||
|
level,
|
||||||
|
row.west_m,
|
||||||
|
row.south_m,
|
||||||
|
row.east_m,
|
||||||
|
row.north_m
|
||||||
|
),
|
||||||
count: row.count,
|
count: row.count,
|
||||||
latitude: row.latitude,
|
latitude: row.latitude,
|
||||||
longitude: row.longitude,
|
longitude: row.longitude,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ defmodule WhoNeedHelp.Help do
|
||||||
alias WhoNeedHelp.Accounts.Scope
|
alias WhoNeedHelp.Accounts.Scope
|
||||||
alias WhoNeedHelp.Catalog
|
alias WhoNeedHelp.Catalog
|
||||||
alias WhoNeedHelp.Catalog.Category
|
alias WhoNeedHelp.Catalog.Category
|
||||||
alias WhoNeedHelp.Help.{Assignment, DiscoveryViewport, HelpRequest}
|
alias WhoNeedHelp.Help.{Assignment, DiscoveryCluster, DiscoveryViewport, HelpRequest}
|
||||||
alias WhoNeedHelp.Pagination
|
alias WhoNeedHelp.Pagination
|
||||||
alias WhoNeedHelp.ProductAnalytics
|
alias WhoNeedHelp.ProductAnalytics
|
||||||
alias WhoNeedHelp.Push
|
alias WhoNeedHelp.Push
|
||||||
|
|
@ -64,12 +64,17 @@ defmodule WhoNeedHelp.Help do
|
||||||
end
|
end
|
||||||
|
|
||||||
def map_discovery_items(%Scope{user: user}, filters, %DiscoveryViewport{} = viewport) do
|
def map_discovery_items(%Scope{user: user}, filters, %DiscoveryViewport{} = viewport) do
|
||||||
cell_size = DiscoveryViewport.cluster_cell_meters(viewport)
|
level = DiscoveryCluster.level_for_zoom(viewport.zoom)
|
||||||
|
cell_size = DiscoveryCluster.cell_size_meters(level)
|
||||||
|
world_half = DiscoveryCluster.world_half_meters()
|
||||||
|
|
||||||
points =
|
points =
|
||||||
user
|
user
|
||||||
|> open_requests_query(filters, nil)
|
|> open_requests_query(filters, nil)
|
||||||
|> where([request], not is_nil(request.location))
|
|> where(
|
||||||
|
[request],
|
||||||
|
not is_nil(request.location) and request.location_visibility != :hidden
|
||||||
|
)
|
||||||
|> filter_request_map_viewport(viewport)
|
|> filter_request_map_viewport(viewport)
|
||||||
|> select([request], %{
|
|> select([request], %{
|
||||||
id: request.id,
|
id: request.id,
|
||||||
|
|
@ -105,14 +110,20 @@ defmodule WhoNeedHelp.Help do
|
||||||
|
|
||||||
points
|
points
|
||||||
|> subquery()
|
|> subquery()
|
||||||
|> group_by(
|
|> group_by([point], [
|
||||||
[point],
|
|
||||||
fragment(
|
fragment(
|
||||||
"ST_SnapToGrid(ST_Transform(?, 3857), ?)",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
|
constant(^cell_size)
|
||||||
|
),
|
||||||
|
fragment(
|
||||||
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
)
|
])
|
||||||
|> select([point], %{
|
|> select([point], %{
|
||||||
count: count(point.id),
|
count: count(point.id),
|
||||||
urgent_count: fragment("count(*) FILTER (WHERE ? = 'now')::bigint", point.urgency),
|
urgent_count: fragment("count(*) FILTER (WHERE ? = 'now')::bigint", point.urgency),
|
||||||
|
|
@ -125,52 +136,59 @@ defmodule WhoNeedHelp.Help do
|
||||||
point.location_visibility
|
point.location_visibility
|
||||||
),
|
),
|
||||||
radius_meters: fragment("CASE WHEN count(*) = 1 THEN max(?) END", point.radius_meters),
|
radius_meters: fragment("CASE WHEN count(*) = 1 THEN max(?) END", point.radius_meters),
|
||||||
longitude:
|
longitude: fragment("avg(ST_X(?))", point.public_location),
|
||||||
fragment(
|
latitude: fragment("avg(ST_Y(?))", point.public_location),
|
||||||
"CASE WHEN count(*) = 1 THEN min(ST_X(?)) ELSE avg(ST_X(?)) END",
|
|
||||||
point.public_location,
|
|
||||||
point.public_location
|
|
||||||
),
|
|
||||||
latitude:
|
|
||||||
fragment(
|
|
||||||
"CASE WHEN count(*) = 1 THEN min(ST_Y(?)) ELSE avg(ST_Y(?)) END",
|
|
||||||
point.public_location,
|
|
||||||
point.public_location
|
|
||||||
),
|
|
||||||
west: fragment("min(ST_X(?))", point.public_location),
|
west: fragment("min(ST_X(?))", point.public_location),
|
||||||
south: fragment("min(ST_Y(?))", point.public_location),
|
south: fragment("min(ST_Y(?))", point.public_location),
|
||||||
east: fragment("max(ST_X(?))", point.public_location),
|
east: fragment("max(ST_X(?))", point.public_location),
|
||||||
north: fragment("max(ST_Y(?))", point.public_location),
|
north: fragment("max(ST_Y(?))", point.public_location),
|
||||||
|
west_m: fragment("min(ST_X(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
south_m: fragment("min(ST_Y(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
east_m: fragment("max(ST_X(ST_Transform(?, 3857)))", point.public_location),
|
||||||
|
north_m: fragment("max(ST_Y(ST_Transform(?, 3857)))", point.public_location),
|
||||||
cell_x:
|
cell_x:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_X(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
),
|
),
|
||||||
cell_y:
|
cell_y:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_Y(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|> order_by(
|
|> order_by([point],
|
||||||
[point],
|
|
||||||
asc:
|
asc:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_X(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_X(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
),
|
),
|
||||||
asc:
|
asc:
|
||||||
fragment(
|
fragment(
|
||||||
"ST_Y(ST_SnapToGrid(ST_Transform(?, 3857), ?))",
|
"floor((ST_Y(ST_Transform(?, 3857)) + ?) / ?)::bigint",
|
||||||
point.public_location,
|
point.public_location,
|
||||||
|
constant(^world_half),
|
||||||
constant(^cell_size)
|
constant(^cell_size)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|> Enum.map(&map_discovery_item(&1, viewport.zoom))
|
|> Enum.map(&map_discovery_item(&1, level))
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_map_discovery_items(%Scope{user: user}, filters) do
|
||||||
|
user
|
||||||
|
|> open_requests_query(filters, nil)
|
||||||
|
|> where(
|
||||||
|
[request],
|
||||||
|
not is_nil(request.location) and request.location_visibility != :hidden
|
||||||
|
)
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Discovery lists include a privacy area's intersection with the viewport.
|
# Discovery lists include a privacy area's intersection with the viewport.
|
||||||
|
|
@ -1274,10 +1292,12 @@ defmodule WhoNeedHelp.Help do
|
||||||
where(query, ^condition)
|
where(query, ^condition)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp map_discovery_item(%{count: 1} = row, _zoom) do
|
defp map_discovery_item(%{count: 1} = row, level) do
|
||||||
%{
|
%{
|
||||||
type: "request",
|
type: "request",
|
||||||
id: row.request_id,
|
id: row.request_id,
|
||||||
|
parent_cluster_id: DiscoveryCluster.parent_id(:request, level, row.cell_x, row.cell_y),
|
||||||
|
hierarchy_level: level,
|
||||||
title: row.title,
|
title: row.title,
|
||||||
location: row.location_label,
|
location: row.location_label,
|
||||||
latitude: row.latitude,
|
latitude: row.latitude,
|
||||||
|
|
@ -1287,15 +1307,24 @@ defmodule WhoNeedHelp.Help do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp map_discovery_item(row, zoom) do
|
defp map_discovery_item(row, level) do
|
||||||
digest =
|
cluster_id = DiscoveryCluster.cluster_id(:request, level, row.cell_x, row.cell_y)
|
||||||
:crypto.hash(:sha256, "#{zoom}:#{row.cell_x}:#{row.cell_y}")
|
|
||||||
|> Base.url_encode64(padding: false)
|
|
||||||
|> binary_part(0, 16)
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
type: "cluster",
|
type: "cluster",
|
||||||
id: "cluster-#{digest}",
|
id: cluster_id,
|
||||||
|
cluster_id: cluster_id,
|
||||||
|
parent_cluster_id: DiscoveryCluster.parent_id(:request, level, row.cell_x, row.cell_y),
|
||||||
|
hierarchy_level: level,
|
||||||
|
point_count: row.count,
|
||||||
|
expansion_zoom:
|
||||||
|
DiscoveryCluster.expansion_zoom(
|
||||||
|
level,
|
||||||
|
row.west_m,
|
||||||
|
row.south_m,
|
||||||
|
row.east_m,
|
||||||
|
row.north_m
|
||||||
|
),
|
||||||
count: row.count,
|
count: row.count,
|
||||||
urgent_count: row.urgent_count,
|
urgent_count: row.urgent_count,
|
||||||
latitude: row.latitude,
|
latitude: row.latitude,
|
||||||
|
|
|
||||||
99
lib/who_need_help/help/discovery_cluster.ex
Normal file
99
lib/who_need_help/help/discovery_cluster.ex
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
defmodule WhoNeedHelp.Help.DiscoveryCluster do
|
||||||
|
@moduledoc """
|
||||||
|
Stable Web Mercator hierarchy used as the server-side input to MapLibre
|
||||||
|
Supercluster.
|
||||||
|
|
||||||
|
A browser cannot safely receive every discovery point once the data set
|
||||||
|
reaches millions of rows. The server therefore groups points into a fixed
|
||||||
|
quadtree. Unlike viewport-sized `ST_SnapToGrid` buckets, every cell has a
|
||||||
|
stable identity and every cell at level `n + 1` belongs to exactly one parent
|
||||||
|
at level `n`.
|
||||||
|
|
||||||
|
MapLibre receives these weighted nodes and applies its native Supercluster
|
||||||
|
implementation for pixel-perfect collision handling. When a server node is
|
||||||
|
reached, `expansion_zoom/5` identifies the first map zoom where that node has
|
||||||
|
more than one child cell.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@world_half_meters 20_037_508.342_789_244
|
||||||
|
@world_width_meters @world_half_meters * 2.0
|
||||||
|
@cluster_level_offset 2
|
||||||
|
@minimum_level 0
|
||||||
|
@maximum_map_zoom 22
|
||||||
|
@maximum_level @maximum_map_zoom + @cluster_level_offset
|
||||||
|
|
||||||
|
@type kind :: :request | :activity
|
||||||
|
|
||||||
|
def level_for_zoom(zoom) when is_number(zoom) do
|
||||||
|
zoom
|
||||||
|
|> floor()
|
||||||
|
|> Kernel.+(@cluster_level_offset)
|
||||||
|
|> clamp(@minimum_level, @maximum_level)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cell_size_meters(level) when is_integer(level) and level in 0..@maximum_level do
|
||||||
|
@world_width_meters / :math.pow(2.0, level)
|
||||||
|
end
|
||||||
|
|
||||||
|
def world_half_meters, do: @world_half_meters
|
||||||
|
|
||||||
|
def cluster_id(kind, level, cell_x, cell_y)
|
||||||
|
when kind in [:request, :activity] and is_integer(level) and is_integer(cell_x) and
|
||||||
|
is_integer(cell_y) do
|
||||||
|
"#{kind}:#{level}:#{cell_x}:#{cell_y}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def parent_id(_kind, 0, _cell_x, _cell_y), do: nil
|
||||||
|
|
||||||
|
def parent_id(kind, level, cell_x, cell_y)
|
||||||
|
when kind in [:request, :activity] and is_integer(level) and level > 0 and
|
||||||
|
is_integer(cell_x) and is_integer(cell_y) do
|
||||||
|
cluster_id(kind, level - 1, div(cell_x, 2), div(cell_y, 2))
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the first map zoom at which a fixed hierarchy cell separates.
|
||||||
|
|
||||||
|
The bounds must be expressed in EPSG:3857 meters and describe the actual
|
||||||
|
member points, not the cell envelope. For coincident points the result is the
|
||||||
|
maximum supported map zoom.
|
||||||
|
"""
|
||||||
|
def expansion_zoom(level, west, south, east, north)
|
||||||
|
when is_integer(level) and is_number(west) and is_number(south) and is_number(east) and
|
||||||
|
is_number(north) do
|
||||||
|
west = clamp_coordinate(west)
|
||||||
|
east = clamp_coordinate(east)
|
||||||
|
south = clamp_coordinate(south)
|
||||||
|
north = clamp_coordinate(north)
|
||||||
|
|
||||||
|
candidate_level =
|
||||||
|
if level >= @maximum_level do
|
||||||
|
@maximum_level
|
||||||
|
else
|
||||||
|
Enum.find((level + 1)..@maximum_level, @maximum_level, fn candidate ->
|
||||||
|
cell_index(west, candidate) != cell_index(east, candidate) or
|
||||||
|
cell_index(south, candidate) != cell_index(north, candidate)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
candidate_level
|
||||||
|
|> Kernel.-(@cluster_level_offset)
|
||||||
|
|> clamp(0, @maximum_map_zoom)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp cell_index(coordinate, level) do
|
||||||
|
coordinate
|
||||||
|
|> Kernel.+(@world_half_meters)
|
||||||
|
|> Kernel./(cell_size_meters(level))
|
||||||
|
|> floor()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp clamp_coordinate(value) do
|
||||||
|
value
|
||||||
|
|> Kernel.*(1.0)
|
||||||
|
|> max(-@world_half_meters)
|
||||||
|
|> min(@world_half_meters - 1.0e-7)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp clamp(value, minimum, maximum), do: value |> max(minimum) |> min(maximum)
|
||||||
|
end
|
||||||
|
|
@ -2,18 +2,18 @@ defmodule WhoNeedHelp.Help.DiscoveryViewport do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Validated map bounds used by request discovery.
|
Validated map bounds used by request discovery.
|
||||||
|
|
||||||
The viewport carries its rendered pixel size so server-side clustering can
|
The viewport carries its rendered pixel size for subscription capacity and
|
||||||
match the amount of detail the browser can actually display. Longitudes
|
input validation. Discovery clustering itself uses a stable zoom-indexed
|
||||||
crossing the antimeridian are represented as two PostGIS envelopes.
|
hierarchy, so a cluster does not change identity when the canvas is resized.
|
||||||
|
Longitudes crossing the antimeridian are represented as two PostGIS
|
||||||
|
envelopes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@max_mercator_latitude 85.051_128_78
|
@max_mercator_latitude 85.051_128_78
|
||||||
@maximum_canvas_dimension 4_096
|
@maximum_canvas_dimension 4_096
|
||||||
@minimum_canvas_dimension 160
|
@minimum_canvas_dimension 160
|
||||||
@cluster_cell_pixels 64.0
|
|
||||||
@map_tile_pixels 256
|
@map_tile_pixels 256
|
||||||
@maximum_subscription_zoom 12
|
@maximum_subscription_zoom 12
|
||||||
@earth_radius_meters 6_378_137.0
|
|
||||||
|
|
||||||
@enforce_keys [:west, :south, :east, :north, :zoom, :width, :height]
|
@enforce_keys [:west, :south, :east, :north, :zoom, :width, :height]
|
||||||
defstruct [:west, :south, :east, :north, :zoom, :width, :height]
|
defstruct [:west, :south, :east, :north, :zoom, :width, :height]
|
||||||
|
|
@ -106,22 +106,6 @@ defmodule WhoNeedHelp.Help.DiscoveryViewport do
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
end
|
end
|
||||||
|
|
||||||
def cluster_cell_meters(%__MODULE__{} = viewport) do
|
|
||||||
horizontal_cells = max(viewport.width / @cluster_cell_pixels, 1.0)
|
|
||||||
vertical_cells = max(viewport.height / @cluster_cell_pixels, 1.0)
|
|
||||||
|
|
||||||
width_meters =
|
|
||||||
viewport
|
|
||||||
|> envelopes()
|
|
||||||
|> Enum.map(fn {west, _south, east, _north} -> mercator_x(east) - mercator_x(west) end)
|
|
||||||
|> Enum.sum()
|
|
||||||
|
|
||||||
height_meters = mercator_y(viewport.north) - mercator_y(viewport.south)
|
|
||||||
|
|
||||||
max(width_meters / horizontal_cells, height_meters / vertical_cells)
|
|
||||||
|> max(0.01)
|
|
||||||
end
|
|
||||||
|
|
||||||
def query_params(%__MODULE__{} = viewport) do
|
def query_params(%__MODULE__{} = viewport) do
|
||||||
%{
|
%{
|
||||||
"west" => format_number(viewport.west),
|
"west" => format_number(viewport.west),
|
||||||
|
|
@ -310,14 +294,6 @@ defmodule WhoNeedHelp.Help.DiscoveryViewport do
|
||||||
defp latitude?(value),
|
defp latitude?(value),
|
||||||
do: value >= -@max_mercator_latitude and value <= @max_mercator_latitude
|
do: value >= -@max_mercator_latitude and value <= @max_mercator_latitude
|
||||||
|
|
||||||
defp mercator_x(longitude), do: @earth_radius_meters * degrees_to_radians(longitude)
|
|
||||||
|
|
||||||
defp mercator_y(latitude) do
|
|
||||||
latitude = min(max(latitude, -@max_mercator_latitude), @max_mercator_latitude)
|
|
||||||
radians = degrees_to_radians(latitude)
|
|
||||||
@earth_radius_meters * :math.log(:math.tan(:math.pi() / 4 + radians / 2))
|
|
||||||
end
|
|
||||||
|
|
||||||
defp degrees_to_radians(value), do: value * :math.pi() / 180.0
|
defp degrees_to_radians(value), do: value * :math.pi() / 180.0
|
||||||
|
|
||||||
defp clamp(value, minimum, maximum), do: min(max(value, minimum), maximum)
|
defp clamp(value, minimum, maximum), do: min(max(value, minimum), maximum)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
|> assign(:activities_cursor, nil)
|
|> assign(:activities_cursor, nil)
|
||||||
|> assign(:map_items, Jason.encode!([]))
|
|> assign(:map_items, Jason.encode!([]))
|
||||||
|> assign(:map_result_count, 0)
|
|> assign(:map_result_count, 0)
|
||||||
|
|> assign(:map_total_count, 0)
|
||||||
|> assign(:discovery_loading, true)
|
|> assign(:discovery_loading, true)
|
||||||
|> assign(:refresh_timer, nil)
|
|> assign(:refresh_timer, nil)
|
||||||
|> assign(:my_activities, [])
|
|> assign(:my_activities, [])
|
||||||
|
|
@ -266,6 +267,15 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
|
|
||||||
activities = activities_page.entries
|
activities = activities_page.entries
|
||||||
|
|
||||||
|
map_total_count =
|
||||||
|
if discovery_mode == "nearby" and view_mode != "list" do
|
||||||
|
DiscoveryQueryCache.fetch(map_total_cache_key(scope, filters), fn ->
|
||||||
|
Activities.count_map_discovery_items(scope, filters)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
|
||||||
%{
|
%{
|
||||||
discovery_loading: false,
|
discovery_loading: false,
|
||||||
activities: activities,
|
activities: activities,
|
||||||
|
|
@ -273,7 +283,8 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
my_activities: my_activities_page.entries,
|
my_activities: my_activities_page.entries,
|
||||||
my_activities_cursor: my_activities_page.next_cursor,
|
my_activities_cursor: my_activities_page.next_cursor,
|
||||||
map_items: Jason.encode!(map_items),
|
map_items: Jason.encode!(map_items),
|
||||||
map_result_count: Enum.reduce(map_items, 0, &(map_item_count(&1) + &2))
|
map_result_count: Enum.reduce(map_items, 0, &(map_item_count(&1) + &2)),
|
||||||
|
map_total_count: map_total_count
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -338,6 +349,11 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
:ok =
|
||||||
|
DiscoveryQueryCache.invalidate(
|
||||||
|
map_total_cache_key(socket.assigns.current_scope, socket.assigns.filters)
|
||||||
|
)
|
||||||
|
|
||||||
socket
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -345,6 +361,8 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
{:activities, scope.user.id, filters, discovery_mode, view_mode, viewport}
|
{:activities, scope.user.id, filters, discovery_mode, view_mode, viewport}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp map_total_cache_key(scope, filters), do: {:activity_map_total, scope.user.id, filters}
|
||||||
|
|
||||||
defp empty_filters, do: %{"category_id" => "", "area" => ""}
|
defp empty_filters, do: %{"category_id" => "", "area" => ""}
|
||||||
|
|
||||||
defp normalize_filters(params) do
|
defp normalize_filters(params) do
|
||||||
|
|
@ -513,6 +531,11 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
count: @map_result_count
|
count: @map_result_count
|
||||||
)}
|
)}
|
||||||
</strong>
|
</strong>
|
||||||
|
<span class="ml-1 text-sm text-base-content/60">
|
||||||
|
{gettext("of %{count} matching activities with map locations",
|
||||||
|
count: @map_total_count
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
<p class="text-sm text-base-content/60">
|
<p class="text-sm text-base-content/60">
|
||||||
{gettext("Move the map, then search the newly visible area.")}
|
{gettext("Move the map, then search the newly visible area.")}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -649,6 +672,9 @@ defmodule WhoNeedHelpWeb.ActivityLive.Index do
|
||||||
data-item-path-prefix="/activities"
|
data-item-path-prefix="/activities"
|
||||||
data-item-label={gettext("Open activity")}
|
data-item-label={gettext("Open activity")}
|
||||||
data-cluster-label={gettext("%{count} activities", count: "%{count}")}
|
data-cluster-label={gettext("%{count} activities", count: "%{count}")}
|
||||||
|
data-cluster-max-zoom-label={
|
||||||
|
gettext("Maximum zoom reached. Matching activities are listed beside the map.")
|
||||||
|
}
|
||||||
data-map-unavailable-label={
|
data-map-unavailable-label={
|
||||||
gettext("The map is unavailable in this browser. Activity details remain usable.")
|
gettext("The map is unavailable in this browser. Activity details remain usable.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
|> assign(:reputation, @empty_reputation)
|
|> assign(:reputation, @empty_reputation)
|
||||||
|> assign(:map_items, Jason.encode!([]))
|
|> assign(:map_items, Jason.encode!([]))
|
||||||
|> assign(:map_result_count, 0)
|
|> assign(:map_result_count, 0)
|
||||||
|
|> assign(:map_total_count, 0)
|
||||||
|> assign(:discovery_loading, true)
|
|> assign(:discovery_loading, true)
|
||||||
|> assign(:refresh_timer, nil)
|
|> assign(:refresh_timer, nil)
|
||||||
|> assign(:page_title, gettext("Nearby help"))
|
|> assign(:page_title, gettext("Nearby help"))
|
||||||
|
|
@ -259,6 +260,15 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
%Pagination.Page{}
|
%Pagination.Page{}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
map_total_count =
|
||||||
|
if discovery_mode == "nearby" and view_mode != "list" do
|
||||||
|
DiscoveryQueryCache.fetch(map_total_cache_key(scope, filters), fn ->
|
||||||
|
Help.count_map_discovery_items(scope, filters)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
|
||||||
%{
|
%{
|
||||||
discovery_loading: false,
|
discovery_loading: false,
|
||||||
requests: requests_page.entries,
|
requests: requests_page.entries,
|
||||||
|
|
@ -267,7 +277,8 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
my_requests_cursor: my_requests_page.next_cursor,
|
my_requests_cursor: my_requests_page.next_cursor,
|
||||||
reputation: Trust.reputation(scope.user.id),
|
reputation: Trust.reputation(scope.user.id),
|
||||||
map_items: Jason.encode!(map_items),
|
map_items: Jason.encode!(map_items),
|
||||||
map_result_count: Enum.reduce(map_items, 0, &(map_item_count(&1) + &2))
|
map_result_count: Enum.reduce(map_items, 0, &(map_item_count(&1) + &2)),
|
||||||
|
map_total_count: map_total_count
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -321,6 +332,11 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
:ok =
|
||||||
|
DiscoveryQueryCache.invalidate(
|
||||||
|
map_total_cache_key(socket.assigns.current_scope, socket.assigns.filters)
|
||||||
|
)
|
||||||
|
|
||||||
socket
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -328,6 +344,8 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
{:requests, scope.user.id, filters, discovery_mode, view_mode, viewport}
|
{:requests, scope.user.id, filters, discovery_mode, view_mode, viewport}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp map_total_cache_key(scope, filters), do: {:request_map_total, scope.user.id, filters}
|
||||||
|
|
||||||
defp empty_filters, do: %{"category_id" => "", "urgency" => "", "area" => ""}
|
defp empty_filters, do: %{"category_id" => "", "urgency" => "", "area" => ""}
|
||||||
|
|
||||||
defp normalize_filters(params) do
|
defp normalize_filters(params) do
|
||||||
|
|
@ -525,6 +543,11 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
count: @map_result_count
|
count: @map_result_count
|
||||||
)}
|
)}
|
||||||
</strong>
|
</strong>
|
||||||
|
<span class="ml-1 text-sm text-base-content/60">
|
||||||
|
{gettext("of %{count} matching requests with map locations",
|
||||||
|
count: @map_total_count
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
<p class="text-sm text-base-content/60">
|
<p class="text-sm text-base-content/60">
|
||||||
{gettext("Move the map, then search the newly visible area.")}
|
{gettext("Move the map, then search the newly visible area.")}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -680,6 +703,9 @@ defmodule WhoNeedHelpWeb.RequestLive.Index do
|
||||||
data-map-retry-label={gettext("Try map again")}
|
data-map-retry-label={gettext("Try map again")}
|
||||||
data-item-label={gettext("Open request")}
|
data-item-label={gettext("Open request")}
|
||||||
data-cluster-label={gettext("%{count} requests", count: "%{count}")}
|
data-cluster-label={gettext("%{count} requests", count: "%{count}")}
|
||||||
|
data-cluster-max-zoom-label={
|
||||||
|
gettext("Maximum zoom reached. Matching requests are listed beside the map.")
|
||||||
|
}
|
||||||
class="aid-map request-discovery-map"
|
class="aid-map request-discovery-map"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ msgid "Active"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:231
|
#: lib/who_need_help_web/components/layouts.ex:231
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:33
|
#: lib/who_need_help_web/live/activity_live/index.ex:37
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -215,7 +215,7 @@ msgstr ""
|
||||||
msgid "Activity restored."
|
msgid "Activity restored."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:427
|
#: lib/who_need_help_web/live/activity_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity type"
|
msgid "Activity type"
|
||||||
|
|
@ -232,12 +232,12 @@ msgstr ""
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:429
|
#: lib/who_need_help_web/live/activity_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All activities"
|
msgid "All activities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:407
|
#: lib/who_need_help_web/live/request_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All categories"
|
msgid "All categories"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -252,7 +252,7 @@ msgstr ""
|
||||||
msgid "Another helper already accepted this request."
|
msgid "Another helper already accepted this request."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:422
|
#: lib/who_need_help_web/live/request_live/index.ex:508
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Any urgency"
|
msgid "Any urgency"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -367,16 +367,16 @@ msgstr ""
|
||||||
msgid "Cancel request"
|
msgid "Cancel request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:358
|
#: lib/who_need_help_web/live/activity_live/index.ex:422
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:327
|
#: lib/who_need_help_web/live/request_live/index.ex:413
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:328
|
#: lib/who_need_help_web/live/request_live/index.ex:414
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:956
|
#: lib/who_need_help_web/live/request_live/show.ex:956
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancelled"
|
msgid "Cancelled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:405
|
#: lib/who_need_help_web/live/request_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:302
|
#: lib/who_need_help_web/live/request_live/new.ex:302
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
|
|
@ -459,7 +459,7 @@ msgstr ""
|
||||||
msgid "Coffee and conversation"
|
msgid "Coffee and conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:372
|
#: lib/who_need_help_web/live/activity_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -474,19 +474,19 @@ msgstr ""
|
||||||
msgid "Community helpers"
|
msgid "Community helpers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:578
|
#: lib/who_need_help_web/live/activity_live/index.ex:647
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:565
|
#: lib/who_need_help_web/live/request_live/index.ex:656
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Community member"
|
msgid "Community member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:357
|
#: lib/who_need_help_web/live/activity_live/index.ex:421
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:325
|
#: lib/who_need_help_web/live/request_live/index.ex:411
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:326
|
#: lib/who_need_help_web/live/request_live/index.ex:412
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:955
|
#: lib/who_need_help_web/live/request_live/show.ex:955
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:974
|
#: lib/who_need_help_web/live/request_live/show.ex:974
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -537,13 +537,13 @@ msgstr ""
|
||||||
msgid "Confirming..."
|
msgid "Confirming..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:378
|
#: lib/who_need_help_web/live/activity_live/index.ex:442
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create activity"
|
msgid "Create activity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:650
|
#: lib/who_need_help_web/live/activity_live/index.ex:722
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create an activity"
|
msgid "Create an activity"
|
||||||
|
|
@ -554,7 +554,7 @@ msgstr ""
|
||||||
msgid "Create category"
|
msgid "Create category"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:356
|
#: lib/who_need_help_web/live/request_live/index.ex:442
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create urgent request"
|
msgid "Create urgent request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -704,7 +704,7 @@ msgstr ""
|
||||||
msgid "Explain what is already arranged and what the volunteer needs to do."
|
msgid "Explain what is already arranged and what the volunteer needs to do."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:369
|
#: lib/who_need_help_web/live/activity_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Find people to join"
|
msgid "Find people to join"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -865,8 +865,8 @@ msgstr ""
|
||||||
msgid "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
msgid "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:323
|
#: lib/who_need_help_web/live/request_live/index.ex:409
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:324
|
#: lib/who_need_help_web/live/request_live/index.ex:410
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:954
|
#: lib/who_need_help_web/live/request_live/show.ex:954
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "In progress"
|
msgid "In progress"
|
||||||
|
|
@ -989,8 +989,8 @@ msgstr ""
|
||||||
msgid "Match and coordinate"
|
msgid "Match and coordinate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:321
|
#: lib/who_need_help_web/live/request_live/index.ex:407
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:322
|
#: lib/who_need_help_web/live/request_live/index.ex:408
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:952
|
#: lib/who_need_help_web/live/request_live/show.ex:952
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Matched"
|
msgid "Matched"
|
||||||
|
|
@ -1016,7 +1016,7 @@ msgstr ""
|
||||||
msgid "Medicine requests"
|
msgid "Medicine requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:385
|
#: lib/who_need_help_web/live/activity_live/index.ex:449
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1067,12 +1067,12 @@ msgstr ""
|
||||||
msgid "Moderator access is required."
|
msgid "Moderator access is required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:347
|
#: lib/who_need_help_web/live/request_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "NEARBY MUTUAL AID"
|
msgid "NEARBY MUTUAL AID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:34
|
#: lib/who_need_help_web/live/request_live/index.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby help"
|
msgid "Nearby help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1153,9 +1153,9 @@ msgid "Not for emergencies"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:748
|
#: lib/who_need_help_web/live/notification_live.ex:748
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:311
|
#: lib/who_need_help_web/live/request_live/index.ex:397
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:312
|
#: lib/who_need_help_web/live/request_live/index.ex:398
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:423
|
#: lib/who_need_help_web/live/request_live/index.ex:509
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:449
|
#: lib/who_need_help_web/live/request_live/new.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:943
|
#: lib/who_need_help_web/live/request_live/show.ex:943
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:944
|
#: lib/who_need_help_web/live/request_live/show.ex:944
|
||||||
|
|
@ -1163,7 +1163,7 @@ msgstr ""
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:367
|
#: lib/who_need_help_web/live/activity_live/index.ex:431
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "OPTIONAL SOCIAL PLANS"
|
msgid "OPTIONAL SOCIAL PLANS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1181,12 +1181,12 @@ msgstr ""
|
||||||
#: lib/who_need_help/notifications/text.ex:140
|
#: lib/who_need_help/notifications/text.ex:140
|
||||||
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
||||||
#: lib/who_need_help_web/controllers/support_html.ex:16
|
#: lib/who_need_help_web/controllers/support_html.ex:16
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:356
|
#: lib/who_need_help_web/live/activity_live/index.ex:420
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:258
|
#: lib/who_need_help_web/live/moderation_live.ex:258
|
||||||
#: lib/who_need_help_web/live/report_live.ex:104
|
#: lib/who_need_help_web/live/report_live.ex:104
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:319
|
#: lib/who_need_help_web/live/request_live/index.ex:405
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:320
|
#: lib/who_need_help_web/live/request_live/index.ex:406
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:951
|
#: lib/who_need_help_web/live/request_live/show.ex:951
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
||||||
|
|
@ -1639,9 +1639,9 @@ msgid "Save profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:750
|
#: lib/who_need_help_web/live/notification_live.ex:750
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:315
|
#: lib/who_need_help_web/live/request_live/index.ex:401
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:316
|
#: lib/who_need_help_web/live/request_live/index.ex:402
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:425
|
#: lib/who_need_help_web/live/request_live/index.ex:511
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:451
|
#: lib/who_need_help_web/live/request_live/new.ex:451
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:947
|
#: lib/who_need_help_web/live/request_live/show.ex:947
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:948
|
#: lib/who_need_help_web/live/request_live/show.ex:948
|
||||||
|
|
@ -1904,7 +1904,7 @@ msgstr ""
|
||||||
msgid "This interaction is blocked."
|
msgid "This interaction is blocked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:363
|
#: lib/who_need_help_web/live/request_live/index.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
||||||
|
|
@ -1952,9 +1952,9 @@ msgid "To see sent emails, visit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:749
|
#: lib/who_need_help_web/live/notification_live.ex:749
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:313
|
#: lib/who_need_help_web/live/request_live/index.ex:399
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:314
|
#: lib/who_need_help_web/live/request_live/index.ex:400
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:424
|
#: lib/who_need_help_web/live/request_live/index.ex:510
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:450
|
#: lib/who_need_help_web/live/request_live/new.ex:450
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:945
|
#: lib/who_need_help_web/live/request_live/show.ex:945
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:946
|
#: lib/who_need_help_web/live/request_live/show.ex:946
|
||||||
|
|
@ -2029,7 +2029,7 @@ msgid "Update email instructions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:743
|
#: lib/who_need_help_web/live/notification_live.ex:743
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:420
|
#: lib/who_need_help_web/live/request_live/index.ex:506
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:447
|
#: lib/who_need_help_web/live/request_live/new.ex:447
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Urgency"
|
msgid "Urgency"
|
||||||
|
|
@ -2174,7 +2174,7 @@ msgstr ""
|
||||||
msgid "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
msgid "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:348
|
#: lib/who_need_help_web/live/request_live/index.ex:434
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Who needs help?"
|
msgid "Who needs help?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2292,7 +2292,7 @@ msgstr ""
|
||||||
msgid "Your review is revealed only after both participants submit."
|
msgid "Your review is revealed only after both participants submit."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:630
|
#: lib/who_need_help_web/live/request_live/index.ex:724
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your trust summary"
|
msgid "Your trust summary"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2313,17 +2313,17 @@ msgstr ""
|
||||||
msgid "before confirming."
|
msgid "before confirming."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:577
|
#: lib/who_need_help_web/live/activity_live/index.ex:646
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:372
|
#: lib/who_need_help_web/live/moderation_live.ex:372
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:564
|
#: lib/who_need_help_web/live/request_live/index.ex:655
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "by %{name}"
|
msgid "by %{name}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:190
|
#: lib/who_need_help_web/live/profile_live.ex:190
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:634
|
#: lib/who_need_help_web/live/request_live/index.ex:728
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "completed"
|
msgid "completed"
|
||||||
|
|
@ -2359,7 +2359,7 @@ msgstr ""
|
||||||
msgid "participants only"
|
msgid "participants only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:638
|
#: lib/who_need_help_web/live/request_live/index.ex:732
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "people"
|
msgid "people"
|
||||||
|
|
@ -2419,7 +2419,7 @@ msgstr ""
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:285
|
#: lib/who_need_help_web/live/profile_live.ex:285
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:642
|
#: lib/who_need_help_web/live/request_live/index.ex:736
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2452,8 +2452,8 @@ msgstr ""
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:329
|
#: lib/who_need_help_web/live/request_live/index.ex:415
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:330
|
#: lib/who_need_help_web/live/request_live/index.ex:416
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2506,8 +2506,8 @@ msgstr ""
|
||||||
msgid "Load earlier messages"
|
msgid "Load earlier messages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:589
|
#: lib/who_need_help_web/live/activity_live/index.ex:658
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
#: lib/who_need_help_web/live/activity_live/index.ex:751
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
||||||
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:465
|
#: lib/who_need_help_web/live/moderation_live.ex:465
|
||||||
|
|
@ -2519,7 +2519,7 @@ msgstr ""
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:363
|
#: lib/who_need_help_web/live/profile_live.ex:363
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
||||||
#: lib/who_need_help_web/live/report_live.ex:98
|
#: lib/who_need_help_web/live/report_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:699
|
#: lib/who_need_help_web/live/request_live/index.ex:805
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2527,7 +2527,7 @@ msgid "Load more"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:610
|
#: lib/who_need_help_web/live/request_live/index.ex:701
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Request details remain usable."
|
msgid "The map is unavailable in this browser. Request details remain usable."
|
||||||
|
|
@ -4516,44 +4516,44 @@ msgstr ""
|
||||||
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:453
|
#: lib/who_need_help_web/live/request_live/index.ex:539
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} request in this map area"
|
msgid "%{count} request in this map area"
|
||||||
msgid_plural "%{count} requests in this map area"
|
msgid_plural "%{count} requests in this map area"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:438
|
#: lib/who_need_help_web/live/activity_live/index.ex:502
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:430
|
#: lib/who_need_help_web/live/request_live/index.ex:516
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Area or city"
|
msgid "Area or city"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:525
|
#: lib/who_need_help_web/live/activity_live/index.ex:594
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:515
|
#: lib/who_need_help_web/live/request_live/index.ex:606
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Choose an area on the map"
|
msgid "Choose an area on the map"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:350
|
#: lib/who_need_help_web/live/request_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:484
|
#: lib/who_need_help_web/live/activity_live/index.ex:553
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:474
|
#: lib/who_need_help_web/live/request_live/index.ex:565
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "List"
|
msgid "List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:586
|
#: lib/who_need_help_web/live/request_live/index.ex:677
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Load more in this area"
|
msgid "Load more in this area"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:504
|
#: lib/who_need_help_web/live/activity_live/index.ex:573
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:494
|
#: lib/who_need_help_web/live/request_live/index.ex:585
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Map"
|
msgid "Map"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -4563,53 +4563,53 @@ msgstr ""
|
||||||
msgid "Map preview"
|
msgid "Map preview"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:537
|
#: lib/who_need_help_web/live/activity_live/index.ex:606
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:527
|
#: lib/who_need_help_web/live/request_live/index.ex:618
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move or zoom the map to search somewhere else."
|
msgid "Move or zoom the map to search somewhere else."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:471
|
#: lib/who_need_help_web/live/activity_live/index.ex:540
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:461
|
#: lib/who_need_help_web/live/request_live/index.ex:552
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move the map, then search the newly visible area."
|
msgid "Move the map, then search the newly visible area."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:525
|
#: lib/who_need_help_web/live/request_live/index.ex:616
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open requests in this area"
|
msgid "No open requests in this area"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:517
|
#: lib/who_need_help_web/live/request_live/index.ex:608
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only requests from the selected map area will be loaded."
|
msgid "Only requests from the selected map area will be loaded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:613
|
#: lib/who_need_help_web/live/request_live/index.ex:704
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open request"
|
msgid "Open request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:439
|
#: lib/who_need_help_web/live/activity_live/index.ex:503
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:431
|
#: lib/who_need_help_web/live/request_live/index.ex:517
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Optional text search"
|
msgid "Optional text search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:592
|
#: lib/who_need_help_web/live/request_live/index.ex:683
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:475
|
#: lib/who_need_help_web/live/activity_live/index.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:465
|
#: lib/who_need_help_web/live/request_live/index.ex:556
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Results layout"
|
msgid "Results layout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:621
|
#: lib/who_need_help_web/live/activity_live/index.ex:693
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:625
|
#: lib/who_need_help_web/live/request_live/index.ex:719
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search this area"
|
msgid "Search this area"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -4619,21 +4619,21 @@ msgstr ""
|
||||||
msgid "Static preview"
|
msgid "Static preview"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:494
|
#: lib/who_need_help_web/live/activity_live/index.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:484
|
#: lib/who_need_help_web/live/request_live/index.ex:575
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Together"
|
msgid "Together"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
||||||
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:609
|
#: lib/who_need_help_web/live/activity_live/index.ex:681
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:602
|
#: lib/who_need_help_web/live/notification_live.ex:602
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:621
|
#: lib/who_need_help_web/live/notification_live.ex:621
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:612
|
#: lib/who_need_help_web/live/request_live/index.ex:703
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:485
|
#: lib/who_need_help_web/live/request_live/new.ex:485
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:563
|
#: lib/who_need_help_web/live/request_live/new.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
||||||
|
|
@ -5022,7 +5022,7 @@ msgid "Nearby alert deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:456
|
#: lib/who_need_help_web/live/notification_live.ex:456
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:376
|
#: lib/who_need_help_web/live/request_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby requests"
|
msgid "Nearby requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -5362,7 +5362,7 @@ msgid "WebGL is unavailable in this browser, so the full map cannot start. Selec
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:610
|
#: lib/who_need_help_web/live/activity_live/index.ex:682
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -5927,7 +5927,7 @@ msgstr ""
|
||||||
msgid "Delivery settings"
|
msgid "Delivery settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:569
|
#: lib/who_need_help_web/live/request_live/index.ex:660
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expires"
|
msgid "Expires"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -5947,29 +5947,29 @@ msgstr ""
|
||||||
msgid "Notification sections"
|
msgid "Notification sections"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:605
|
#: lib/who_need_help_web/live/activity_live/index.ex:674
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activities"
|
msgid "%{count} activities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activity in this map area"
|
msgid "%{count} activity in this map area"
|
||||||
msgid_plural "%{count} activities in this map area"
|
msgid_plural "%{count} activities in this map area"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:614
|
#: lib/who_need_help_web/live/request_live/index.ex:705
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} requests"
|
msgid "%{count} requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:645
|
#: lib/who_need_help_web/live/activity_live/index.ex:717
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:393
|
#: lib/who_need_help_web/live/activity_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity views"
|
msgid "Activity views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -5984,12 +5984,12 @@ msgstr ""
|
||||||
msgid "Confirm the safety guidance before asking nearby people for help."
|
msgid "Confirm the safety guidance before asking nearby people for help."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:659
|
#: lib/who_need_help_web/live/request_live/index.ex:753
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create request"
|
msgid "Create request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:673
|
#: lib/who_need_help_web/live/request_live/index.ex:776
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create your first request"
|
msgid "Create your first request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -6004,43 +6004,43 @@ msgstr ""
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:399
|
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My activities"
|
msgid "My activities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:377
|
#: lib/who_need_help_web/live/request_live/index.ex:463
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:653
|
#: lib/who_need_help_web/live/request_live/index.ex:747
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My requests"
|
msgid "My requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:398
|
#: lib/who_need_help_web/live/activity_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby activities"
|
msgid "Nearby activities"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:643
|
#: lib/who_need_help_web/live/activity_live/index.ex:715
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No activities yet"
|
msgid "No activities yet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open activities in this area"
|
msgid "No open activities in this area"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:668
|
#: lib/who_need_help_web/live/request_live/index.ex:771
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No requests yet"
|
msgid "No requests yet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
#: lib/who_need_help_web/live/activity_live/index.ex:596
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only activities from the selected map area will be loaded."
|
msgid "Only activities from the selected map area will be loaded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
#: lib/who_need_help_web/live/activity_live/index.ex:673
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open activity"
|
msgid "Open activity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -6050,12 +6050,12 @@ msgstr ""
|
||||||
msgid "Request form steps"
|
msgid "Request form steps"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:371
|
#: lib/who_need_help_web/live/request_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Request views"
|
msgid "Request views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:670
|
#: lib/who_need_help_web/live/request_live/index.ex:773
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests you publish or accept will appear here."
|
msgid "Requests you publish or accept will appear here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -6080,7 +6080,7 @@ msgstr ""
|
||||||
msgid "Share only as much location detail as helpers need."
|
msgid "Share only as much location detail as helpers need."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:607
|
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Activity details remain usable."
|
msgid "The map is unavailable in this browser. Activity details remain usable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -6090,7 +6090,7 @@ msgstr ""
|
||||||
msgid "Timing"
|
msgid "Timing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:655
|
#: lib/who_need_help_web/live/request_live/index.ex:749
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Track requests you created and requests you accepted as a helper."
|
msgid "Track requests you created and requests you accepted as a helper."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -6751,11 +6751,32 @@ msgstr ""
|
||||||
msgid "Choose the meeting point on the map or use your current location."
|
msgid "Choose the meeting point on the map or use your current location."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:458
|
#: lib/who_need_help_web/live/activity_live/index.ex:522
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:517
|
#: lib/who_need_help_web/live/activity_live/index.ex:586
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:635
|
#: lib/who_need_help_web/live/activity_live/index.ex:707
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:448
|
#: lib/who_need_help_web/live/request_live/index.ex:534
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:507
|
#: lib/who_need_help_web/live/request_live/index.ex:598
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:763
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loading results…"
|
msgid "Loading results…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:676
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching activities are listed beside the map."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:707
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching requests are listed beside the map."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching activities with map locations"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:547
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching requests with map locations"
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ msgid "Active"
|
||||||
msgstr "Active"
|
msgstr "Active"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:231
|
#: lib/who_need_help_web/components/layouts.ex:231
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:33
|
#: lib/who_need_help_web/live/activity_live/index.ex:37
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Activities"
|
msgstr "Activities"
|
||||||
|
|
@ -215,7 +215,7 @@ msgstr "Activity published. You approve every participant."
|
||||||
msgid "Activity restored."
|
msgid "Activity restored."
|
||||||
msgstr "Activity restored."
|
msgstr "Activity restored."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:427
|
#: lib/who_need_help_web/live/activity_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity type"
|
msgid "Activity type"
|
||||||
|
|
@ -232,12 +232,12 @@ msgstr "Add unverified link"
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:429
|
#: lib/who_need_help_web/live/activity_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All activities"
|
msgid "All activities"
|
||||||
msgstr "All activities"
|
msgstr "All activities"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:407
|
#: lib/who_need_help_web/live/request_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All categories"
|
msgid "All categories"
|
||||||
msgstr "All categories"
|
msgstr "All categories"
|
||||||
|
|
@ -252,7 +252,7 @@ msgstr "Already registered?"
|
||||||
msgid "Another helper already accepted this request."
|
msgid "Another helper already accepted this request."
|
||||||
msgstr "Another helper already accepted this request."
|
msgstr "Another helper already accepted this request."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:422
|
#: lib/who_need_help_web/live/request_live/index.ex:508
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Any urgency"
|
msgid "Any urgency"
|
||||||
msgstr "Any urgency"
|
msgstr "Any urgency"
|
||||||
|
|
@ -367,16 +367,16 @@ msgstr "Cancel activity"
|
||||||
msgid "Cancel request"
|
msgid "Cancel request"
|
||||||
msgstr "Cancel request"
|
msgstr "Cancel request"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:358
|
#: lib/who_need_help_web/live/activity_live/index.ex:422
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:327
|
#: lib/who_need_help_web/live/request_live/index.ex:413
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:328
|
#: lib/who_need_help_web/live/request_live/index.ex:414
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:956
|
#: lib/who_need_help_web/live/request_live/show.ex:956
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancelled"
|
msgid "Cancelled"
|
||||||
msgstr "Cancelled"
|
msgstr "Cancelled"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:405
|
#: lib/who_need_help_web/live/request_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:302
|
#: lib/who_need_help_web/live/request_live/new.ex:302
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
|
|
@ -459,7 +459,7 @@ msgstr "Close"
|
||||||
msgid "Coffee and conversation"
|
msgid "Coffee and conversation"
|
||||||
msgstr "Coffee and conversation"
|
msgstr "Coffee and conversation"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:372
|
#: lib/who_need_help_web/live/activity_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
||||||
msgstr "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
msgstr "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
||||||
|
|
@ -474,19 +474,19 @@ msgstr "Comment (optional)"
|
||||||
msgid "Community helpers"
|
msgid "Community helpers"
|
||||||
msgstr "Community helpers"
|
msgstr "Community helpers"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:578
|
#: lib/who_need_help_web/live/activity_live/index.ex:647
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:565
|
#: lib/who_need_help_web/live/request_live/index.ex:656
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Community member"
|
msgid "Community member"
|
||||||
msgstr "Community member"
|
msgstr "Community member"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:357
|
#: lib/who_need_help_web/live/activity_live/index.ex:421
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:325
|
#: lib/who_need_help_web/live/request_live/index.ex:411
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:326
|
#: lib/who_need_help_web/live/request_live/index.ex:412
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:955
|
#: lib/who_need_help_web/live/request_live/show.ex:955
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:974
|
#: lib/who_need_help_web/live/request_live/show.ex:974
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -537,13 +537,13 @@ msgstr "Confirmation instructions"
|
||||||
msgid "Confirming..."
|
msgid "Confirming..."
|
||||||
msgstr "Confirming..."
|
msgstr "Confirming..."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:378
|
#: lib/who_need_help_web/live/activity_live/index.ex:442
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create activity"
|
msgid "Create activity"
|
||||||
msgstr "Create activity"
|
msgstr "Create activity"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:650
|
#: lib/who_need_help_web/live/activity_live/index.ex:722
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create an activity"
|
msgid "Create an activity"
|
||||||
|
|
@ -554,7 +554,7 @@ msgstr "Create an activity"
|
||||||
msgid "Create category"
|
msgid "Create category"
|
||||||
msgstr "Create category"
|
msgstr "Create category"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:356
|
#: lib/who_need_help_web/live/request_live/index.ex:442
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create urgent request"
|
msgid "Create urgent request"
|
||||||
msgstr "Create urgent request"
|
msgstr "Create urgent request"
|
||||||
|
|
@ -704,7 +704,7 @@ msgstr "Expires:"
|
||||||
msgid "Explain what is already arranged and what the volunteer needs to do."
|
msgid "Explain what is already arranged and what the volunteer needs to do."
|
||||||
msgstr "Explain what is already arranged and what the volunteer needs to do."
|
msgstr "Explain what is already arranged and what the volunteer needs to do."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:369
|
#: lib/who_need_help_web/live/activity_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Find people to join"
|
msgid "Find people to join"
|
||||||
msgstr "Find people to join"
|
msgstr "Find people to join"
|
||||||
|
|
@ -865,8 +865,8 @@ msgstr "Impersonation"
|
||||||
msgid "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
msgid "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
||||||
msgstr "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
msgstr "In a browser this works only while the page remains open. The Android app shows a persistent notification and can continue after it is minimized. Raw coordinates are removed when sharing stops."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:323
|
#: lib/who_need_help_web/live/request_live/index.ex:409
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:324
|
#: lib/who_need_help_web/live/request_live/index.ex:410
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:954
|
#: lib/who_need_help_web/live/request_live/show.ex:954
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "In progress"
|
msgid "In progress"
|
||||||
|
|
@ -989,8 +989,8 @@ msgstr "Mark completed"
|
||||||
msgid "Match and coordinate"
|
msgid "Match and coordinate"
|
||||||
msgstr "Match and coordinate"
|
msgstr "Match and coordinate"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:321
|
#: lib/who_need_help_web/live/request_live/index.ex:407
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:322
|
#: lib/who_need_help_web/live/request_live/index.ex:408
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:952
|
#: lib/who_need_help_web/live/request_live/show.ex:952
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Matched"
|
msgid "Matched"
|
||||||
|
|
@ -1016,7 +1016,7 @@ msgstr "Medicine pickup remains the first priority. Roadside categories use the
|
||||||
msgid "Medicine requests"
|
msgid "Medicine requests"
|
||||||
msgstr "Medicine requests"
|
msgstr "Medicine requests"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:385
|
#: lib/who_need_help_web/live/activity_live/index.ex:449
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
||||||
msgstr "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
msgstr "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
||||||
|
|
@ -1067,12 +1067,12 @@ msgstr "Moderator"
|
||||||
msgid "Moderator access is required."
|
msgid "Moderator access is required."
|
||||||
msgstr "Moderator access is required."
|
msgstr "Moderator access is required."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:347
|
#: lib/who_need_help_web/live/request_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "NEARBY MUTUAL AID"
|
msgid "NEARBY MUTUAL AID"
|
||||||
msgstr "NEARBY MUTUAL AID"
|
msgstr "NEARBY MUTUAL AID"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:34
|
#: lib/who_need_help_web/live/request_live/index.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby help"
|
msgid "Nearby help"
|
||||||
msgstr "Nearby help"
|
msgstr "Nearby help"
|
||||||
|
|
@ -1153,9 +1153,9 @@ msgid "Not for emergencies"
|
||||||
msgstr "Not for emergencies"
|
msgstr "Not for emergencies"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:748
|
#: lib/who_need_help_web/live/notification_live.ex:748
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:311
|
#: lib/who_need_help_web/live/request_live/index.ex:397
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:312
|
#: lib/who_need_help_web/live/request_live/index.ex:398
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:423
|
#: lib/who_need_help_web/live/request_live/index.ex:509
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:449
|
#: lib/who_need_help_web/live/request_live/new.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:943
|
#: lib/who_need_help_web/live/request_live/show.ex:943
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:944
|
#: lib/who_need_help_web/live/request_live/show.ex:944
|
||||||
|
|
@ -1163,7 +1163,7 @@ msgstr "Not for emergencies"
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Now"
|
msgstr "Now"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:367
|
#: lib/who_need_help_web/live/activity_live/index.ex:431
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "OPTIONAL SOCIAL PLANS"
|
msgid "OPTIONAL SOCIAL PLANS"
|
||||||
msgstr "OPTIONAL SOCIAL PLANS"
|
msgstr "OPTIONAL SOCIAL PLANS"
|
||||||
|
|
@ -1181,12 +1181,12 @@ msgstr "Only the organizer and approved participants can read or send these mess
|
||||||
#: lib/who_need_help/notifications/text.ex:140
|
#: lib/who_need_help/notifications/text.ex:140
|
||||||
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
||||||
#: lib/who_need_help_web/controllers/support_html.ex:16
|
#: lib/who_need_help_web/controllers/support_html.ex:16
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:356
|
#: lib/who_need_help_web/live/activity_live/index.ex:420
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:258
|
#: lib/who_need_help_web/live/moderation_live.ex:258
|
||||||
#: lib/who_need_help_web/live/report_live.ex:104
|
#: lib/who_need_help_web/live/report_live.ex:104
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:319
|
#: lib/who_need_help_web/live/request_live/index.ex:405
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:320
|
#: lib/who_need_help_web/live/request_live/index.ex:406
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:951
|
#: lib/who_need_help_web/live/request_live/show.ex:951
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
||||||
|
|
@ -1639,9 +1639,9 @@ msgid "Save profile"
|
||||||
msgstr "Save profile"
|
msgstr "Save profile"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:750
|
#: lib/who_need_help_web/live/notification_live.ex:750
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:315
|
#: lib/who_need_help_web/live/request_live/index.ex:401
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:316
|
#: lib/who_need_help_web/live/request_live/index.ex:402
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:425
|
#: lib/who_need_help_web/live/request_live/index.ex:511
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:451
|
#: lib/who_need_help_web/live/request_live/new.ex:451
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:947
|
#: lib/who_need_help_web/live/request_live/show.ex:947
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:948
|
#: lib/who_need_help_web/live/request_live/show.ex:948
|
||||||
|
|
@ -1904,7 +1904,7 @@ msgstr "This activity state has already changed."
|
||||||
msgid "This interaction is blocked."
|
msgid "This interaction is blocked."
|
||||||
msgstr "This interaction is blocked."
|
msgstr "This interaction is blocked."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:363
|
#: lib/who_need_help_web/live/request_live/index.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
||||||
|
|
@ -1952,9 +1952,9 @@ msgid "To see sent emails, visit"
|
||||||
msgstr "To see sent emails, visit"
|
msgstr "To see sent emails, visit"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:749
|
#: lib/who_need_help_web/live/notification_live.ex:749
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:313
|
#: lib/who_need_help_web/live/request_live/index.ex:399
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:314
|
#: lib/who_need_help_web/live/request_live/index.ex:400
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:424
|
#: lib/who_need_help_web/live/request_live/index.ex:510
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:450
|
#: lib/who_need_help_web/live/request_live/new.ex:450
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:945
|
#: lib/who_need_help_web/live/request_live/show.ex:945
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:946
|
#: lib/who_need_help_web/live/request_live/show.ex:946
|
||||||
|
|
@ -2029,7 +2029,7 @@ msgid "Update email instructions"
|
||||||
msgstr "Update email instructions"
|
msgstr "Update email instructions"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:743
|
#: lib/who_need_help_web/live/notification_live.ex:743
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:420
|
#: lib/who_need_help_web/live/request_live/index.ex:506
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:447
|
#: lib/who_need_help_web/live/request_live/new.ex:447
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Urgency"
|
msgid "Urgency"
|
||||||
|
|
@ -2174,7 +2174,7 @@ msgstr "Who Need Help home"
|
||||||
msgid "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
msgid "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
||||||
msgstr "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
msgstr "Who Need Help was developed with the local Codex CLI authenticated through the builder's ChatGPT subscription. No OpenAI API key or usage-based API fallback is used."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:348
|
#: lib/who_need_help_web/live/request_live/index.ex:434
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Who needs help?"
|
msgid "Who needs help?"
|
||||||
msgstr "Who needs help?"
|
msgstr "Who needs help?"
|
||||||
|
|
@ -2292,7 +2292,7 @@ msgstr "Your requests"
|
||||||
msgid "Your review is revealed only after both participants submit."
|
msgid "Your review is revealed only after both participants submit."
|
||||||
msgstr "Your review is revealed only after both participants submit."
|
msgstr "Your review is revealed only after both participants submit."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:630
|
#: lib/who_need_help_web/live/request_live/index.ex:724
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your trust summary"
|
msgid "Your trust summary"
|
||||||
msgstr "Your trust summary"
|
msgstr "Your trust summary"
|
||||||
|
|
@ -2313,17 +2313,17 @@ msgstr "activity message"
|
||||||
msgid "before confirming."
|
msgid "before confirming."
|
||||||
msgstr "before confirming."
|
msgstr "before confirming."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:577
|
#: lib/who_need_help_web/live/activity_live/index.ex:646
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:372
|
#: lib/who_need_help_web/live/moderation_live.ex:372
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:564
|
#: lib/who_need_help_web/live/request_live/index.ex:655
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "by %{name}"
|
msgid "by %{name}"
|
||||||
msgstr "by %{name}"
|
msgstr "by %{name}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:190
|
#: lib/who_need_help_web/live/profile_live.ex:190
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:634
|
#: lib/who_need_help_web/live/request_live/index.ex:728
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "completed"
|
msgid "completed"
|
||||||
|
|
@ -2359,7 +2359,7 @@ msgstr "organizer"
|
||||||
msgid "participants only"
|
msgid "participants only"
|
||||||
msgstr "participants only"
|
msgstr "participants only"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:638
|
#: lib/who_need_help_web/live/request_live/index.ex:732
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "people"
|
msgid "people"
|
||||||
|
|
@ -2419,7 +2419,7 @@ msgstr "urgent"
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:285
|
#: lib/who_need_help_web/live/profile_live.ex:285
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:642
|
#: lib/who_need_help_web/live/request_live/index.ex:736
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2452,8 +2452,8 @@ msgstr "← Requests"
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Approved"
|
msgstr "Approved"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:329
|
#: lib/who_need_help_web/live/request_live/index.ex:415
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:330
|
#: lib/who_need_help_web/live/request_live/index.ex:416
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr "Expired"
|
msgstr "Expired"
|
||||||
|
|
@ -2506,8 +2506,8 @@ msgstr "Unusual action rate"
|
||||||
msgid "Load earlier messages"
|
msgid "Load earlier messages"
|
||||||
msgstr "Load earlier messages"
|
msgstr "Load earlier messages"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:589
|
#: lib/who_need_help_web/live/activity_live/index.ex:658
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
#: lib/who_need_help_web/live/activity_live/index.ex:751
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
||||||
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:465
|
#: lib/who_need_help_web/live/moderation_live.ex:465
|
||||||
|
|
@ -2519,7 +2519,7 @@ msgstr "Load earlier messages"
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:363
|
#: lib/who_need_help_web/live/profile_live.ex:363
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
||||||
#: lib/who_need_help_web/live/report_live.ex:98
|
#: lib/who_need_help_web/live/report_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:699
|
#: lib/who_need_help_web/live/request_live/index.ex:805
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2527,7 +2527,7 @@ msgid "Load more"
|
||||||
msgstr "Load more"
|
msgstr "Load more"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:610
|
#: lib/who_need_help_web/live/request_live/index.ex:701
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Request details remain usable."
|
msgid "The map is unavailable in this browser. Request details remain usable."
|
||||||
|
|
@ -4516,44 +4516,44 @@ msgstr ""
|
||||||
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:453
|
#: lib/who_need_help_web/live/request_live/index.ex:539
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} request in this map area"
|
msgid "%{count} request in this map area"
|
||||||
msgid_plural "%{count} requests in this map area"
|
msgid_plural "%{count} requests in this map area"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:438
|
#: lib/who_need_help_web/live/activity_live/index.ex:502
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:430
|
#: lib/who_need_help_web/live/request_live/index.ex:516
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Area or city"
|
msgid "Area or city"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:525
|
#: lib/who_need_help_web/live/activity_live/index.ex:594
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:515
|
#: lib/who_need_help_web/live/request_live/index.ex:606
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Choose an area on the map"
|
msgid "Choose an area on the map"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:350
|
#: lib/who_need_help_web/live/request_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:484
|
#: lib/who_need_help_web/live/activity_live/index.ex:553
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:474
|
#: lib/who_need_help_web/live/request_live/index.ex:565
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "List"
|
msgid "List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:586
|
#: lib/who_need_help_web/live/request_live/index.ex:677
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Load more in this area"
|
msgid "Load more in this area"
|
||||||
msgstr "Load more in this area"
|
msgstr "Load more in this area"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:504
|
#: lib/who_need_help_web/live/activity_live/index.ex:573
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:494
|
#: lib/who_need_help_web/live/request_live/index.ex:585
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Map"
|
msgid "Map"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -4563,53 +4563,53 @@ msgstr ""
|
||||||
msgid "Map preview"
|
msgid "Map preview"
|
||||||
msgstr "Map preview"
|
msgstr "Map preview"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:537
|
#: lib/who_need_help_web/live/activity_live/index.ex:606
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:527
|
#: lib/who_need_help_web/live/request_live/index.ex:618
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move or zoom the map to search somewhere else."
|
msgid "Move or zoom the map to search somewhere else."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:471
|
#: lib/who_need_help_web/live/activity_live/index.ex:540
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:461
|
#: lib/who_need_help_web/live/request_live/index.ex:552
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move the map, then search the newly visible area."
|
msgid "Move the map, then search the newly visible area."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:525
|
#: lib/who_need_help_web/live/request_live/index.ex:616
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open requests in this area"
|
msgid "No open requests in this area"
|
||||||
msgstr "No open requests in this area"
|
msgstr "No open requests in this area"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:517
|
#: lib/who_need_help_web/live/request_live/index.ex:608
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only requests from the selected map area will be loaded."
|
msgid "Only requests from the selected map area will be loaded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:613
|
#: lib/who_need_help_web/live/request_live/index.ex:704
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open request"
|
msgid "Open request"
|
||||||
msgstr "Open request"
|
msgstr "Open request"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:439
|
#: lib/who_need_help_web/live/activity_live/index.ex:503
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:431
|
#: lib/who_need_help_web/live/request_live/index.ex:517
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Optional text search"
|
msgid "Optional text search"
|
||||||
msgstr "Optional text search"
|
msgstr "Optional text search"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:592
|
#: lib/who_need_help_web/live/request_live/index.ex:683
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:475
|
#: lib/who_need_help_web/live/activity_live/index.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:465
|
#: lib/who_need_help_web/live/request_live/index.ex:556
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Results layout"
|
msgid "Results layout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:621
|
#: lib/who_need_help_web/live/activity_live/index.ex:693
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:625
|
#: lib/who_need_help_web/live/request_live/index.ex:719
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search this area"
|
msgid "Search this area"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -4619,21 +4619,21 @@ msgstr ""
|
||||||
msgid "Static preview"
|
msgid "Static preview"
|
||||||
msgstr "Static preview"
|
msgstr "Static preview"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:494
|
#: lib/who_need_help_web/live/activity_live/index.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:484
|
#: lib/who_need_help_web/live/request_live/index.ex:575
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Together"
|
msgid "Together"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
||||||
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:609
|
#: lib/who_need_help_web/live/activity_live/index.ex:681
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:602
|
#: lib/who_need_help_web/live/notification_live.ex:602
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:621
|
#: lib/who_need_help_web/live/notification_live.ex:621
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:612
|
#: lib/who_need_help_web/live/request_live/index.ex:703
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:485
|
#: lib/who_need_help_web/live/request_live/new.ex:485
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:563
|
#: lib/who_need_help_web/live/request_live/new.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
||||||
|
|
@ -5022,7 +5022,7 @@ msgid "Nearby alert deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:456
|
#: lib/who_need_help_web/live/notification_live.ex:456
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:376
|
#: lib/who_need_help_web/live/request_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby requests"
|
msgid "Nearby requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -5362,7 +5362,7 @@ msgid "WebGL is unavailable in this browser, so the full map cannot start. Selec
|
||||||
msgstr "WebGL is unavailable in this browser, so the full map cannot start. Select an example below or retry the map."
|
msgstr "WebGL is unavailable in this browser, so the full map cannot start. Select an example below or retry the map."
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:610
|
#: lib/who_need_help_web/live/activity_live/index.ex:682
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -5927,7 +5927,7 @@ msgstr "Your review is now visible"
|
||||||
msgid "Delivery settings"
|
msgid "Delivery settings"
|
||||||
msgstr "Delivery settings"
|
msgstr "Delivery settings"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:569
|
#: lib/who_need_help_web/live/request_live/index.ex:660
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expires"
|
msgid "Expires"
|
||||||
msgstr "Expires"
|
msgstr "Expires"
|
||||||
|
|
@ -5947,29 +5947,29 @@ msgstr "Nearby alerts"
|
||||||
msgid "Notification sections"
|
msgid "Notification sections"
|
||||||
msgstr "Notification sections"
|
msgstr "Notification sections"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:605
|
#: lib/who_need_help_web/live/activity_live/index.ex:674
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activities"
|
msgid "%{count} activities"
|
||||||
msgstr "%{count} activities"
|
msgstr "%{count} activities"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activity in this map area"
|
msgid "%{count} activity in this map area"
|
||||||
msgid_plural "%{count} activities in this map area"
|
msgid_plural "%{count} activities in this map area"
|
||||||
msgstr[0] "%{count} activity in this map area"
|
msgstr[0] "%{count} activity in this map area"
|
||||||
msgstr[1] "%{count} activities in this map area"
|
msgstr[1] "%{count} activities in this map area"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:614
|
#: lib/who_need_help_web/live/request_live/index.ex:705
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} requests"
|
msgid "%{count} requests"
|
||||||
msgstr "%{count} requests"
|
msgstr "%{count} requests"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:645
|
#: lib/who_need_help_web/live/activity_live/index.ex:717
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
||||||
msgstr "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
msgstr "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:393
|
#: lib/who_need_help_web/live/activity_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity views"
|
msgid "Activity views"
|
||||||
msgstr "Activity views"
|
msgstr "Activity views"
|
||||||
|
|
@ -5984,12 +5984,12 @@ msgstr "Choose a category and describe the task clearly."
|
||||||
msgid "Confirm the safety guidance before asking nearby people for help."
|
msgid "Confirm the safety guidance before asking nearby people for help."
|
||||||
msgstr "Confirm the safety guidance before asking nearby people for help."
|
msgstr "Confirm the safety guidance before asking nearby people for help."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:659
|
#: lib/who_need_help_web/live/request_live/index.ex:753
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create request"
|
msgid "Create request"
|
||||||
msgstr "Create request"
|
msgstr "Create request"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:673
|
#: lib/who_need_help_web/live/request_live/index.ex:776
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create your first request"
|
msgid "Create your first request"
|
||||||
msgstr "Create your first request"
|
msgstr "Create your first request"
|
||||||
|
|
@ -6004,43 +6004,43 @@ msgstr "Help details"
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Location"
|
msgstr "Location"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:399
|
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My activities"
|
msgid "My activities"
|
||||||
msgstr "My activities"
|
msgstr "My activities"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:377
|
#: lib/who_need_help_web/live/request_live/index.ex:463
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:653
|
#: lib/who_need_help_web/live/request_live/index.ex:747
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My requests"
|
msgid "My requests"
|
||||||
msgstr "My requests"
|
msgstr "My requests"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:398
|
#: lib/who_need_help_web/live/activity_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby activities"
|
msgid "Nearby activities"
|
||||||
msgstr "Nearby activities"
|
msgstr "Nearby activities"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:643
|
#: lib/who_need_help_web/live/activity_live/index.ex:715
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No activities yet"
|
msgid "No activities yet"
|
||||||
msgstr "No activities yet"
|
msgstr "No activities yet"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open activities in this area"
|
msgid "No open activities in this area"
|
||||||
msgstr "No open activities in this area"
|
msgstr "No open activities in this area"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:668
|
#: lib/who_need_help_web/live/request_live/index.ex:771
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No requests yet"
|
msgid "No requests yet"
|
||||||
msgstr "No requests yet"
|
msgstr "No requests yet"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
#: lib/who_need_help_web/live/activity_live/index.ex:596
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only activities from the selected map area will be loaded."
|
msgid "Only activities from the selected map area will be loaded."
|
||||||
msgstr "Only activities from the selected map area will be loaded."
|
msgstr "Only activities from the selected map area will be loaded."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
#: lib/who_need_help_web/live/activity_live/index.ex:673
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open activity"
|
msgid "Open activity"
|
||||||
msgstr "Open activity"
|
msgstr "Open activity"
|
||||||
|
|
@ -6050,12 +6050,12 @@ msgstr "Open activity"
|
||||||
msgid "Request form steps"
|
msgid "Request form steps"
|
||||||
msgstr "Request form steps"
|
msgstr "Request form steps"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:371
|
#: lib/who_need_help_web/live/request_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Request views"
|
msgid "Request views"
|
||||||
msgstr "Request views"
|
msgstr "Request views"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:670
|
#: lib/who_need_help_web/live/request_live/index.ex:773
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests you publish or accept will appear here."
|
msgid "Requests you publish or accept will appear here."
|
||||||
msgstr "Requests you publish or accept will appear here."
|
msgstr "Requests you publish or accept will appear here."
|
||||||
|
|
@ -6080,7 +6080,7 @@ msgstr "Set urgency and when this request should close."
|
||||||
msgid "Share only as much location detail as helpers need."
|
msgid "Share only as much location detail as helpers need."
|
||||||
msgstr "Share only as much location detail as helpers need."
|
msgstr "Share only as much location detail as helpers need."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:607
|
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Activity details remain usable."
|
msgid "The map is unavailable in this browser. Activity details remain usable."
|
||||||
msgstr "The map is unavailable in this browser. Activity details remain usable."
|
msgstr "The map is unavailable in this browser. Activity details remain usable."
|
||||||
|
|
@ -6090,7 +6090,7 @@ msgstr "The map is unavailable in this browser. Activity details remain usable."
|
||||||
msgid "Timing"
|
msgid "Timing"
|
||||||
msgstr "Timing"
|
msgstr "Timing"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:655
|
#: lib/who_need_help_web/live/request_live/index.ex:749
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Track requests you created and requests you accepted as a helper."
|
msgid "Track requests you created and requests you accepted as a helper."
|
||||||
msgstr "Track requests you created and requests you accepted as a helper."
|
msgstr "Track requests you created and requests you accepted as a helper."
|
||||||
|
|
@ -6751,11 +6751,32 @@ msgstr "What should people see before approval?"
|
||||||
msgid "Choose the meeting point on the map or use your current location."
|
msgid "Choose the meeting point on the map or use your current location."
|
||||||
msgstr "Choose the meeting point on the map or use your current location."
|
msgstr "Choose the meeting point on the map or use your current location."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:458
|
#: lib/who_need_help_web/live/activity_live/index.ex:522
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:517
|
#: lib/who_need_help_web/live/activity_live/index.ex:586
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:635
|
#: lib/who_need_help_web/live/activity_live/index.ex:707
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:448
|
#: lib/who_need_help_web/live/request_live/index.ex:534
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:507
|
#: lib/who_need_help_web/live/request_live/index.ex:598
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:763
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loading results…"
|
msgid "Loading results…"
|
||||||
msgstr "Loading results…"
|
msgstr "Loading results…"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:676
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching activities are listed beside the map."
|
||||||
|
msgstr "Maximum zoom reached. Matching activities are listed beside the map."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:707
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching requests are listed beside the map."
|
||||||
|
msgstr "Maximum zoom reached. Matching requests are listed beside the map."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching activities with map locations"
|
||||||
|
msgstr "of %{count} matching activities with map locations"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:547
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching requests with map locations"
|
||||||
|
msgstr "of %{count} matching requests with map locations"
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ msgid "Active"
|
||||||
msgstr "Активный"
|
msgstr "Активный"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:231
|
#: lib/who_need_help_web/components/layouts.ex:231
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:33
|
#: lib/who_need_help_web/live/activity_live/index.ex:37
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Активности"
|
msgstr "Активности"
|
||||||
|
|
@ -226,7 +226,7 @@ msgstr "Активность опубликована. Вы одобряете
|
||||||
msgid "Activity restored."
|
msgid "Activity restored."
|
||||||
msgstr "Активность восстановлена."
|
msgstr "Активность восстановлена."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:427
|
#: lib/who_need_help_web/live/activity_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity type"
|
msgid "Activity type"
|
||||||
|
|
@ -243,12 +243,12 @@ msgstr "Добавить неподтверждённую ссылку"
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Администратор"
|
msgstr "Администратор"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:429
|
#: lib/who_need_help_web/live/activity_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All activities"
|
msgid "All activities"
|
||||||
msgstr "Все активности"
|
msgstr "Все активности"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:407
|
#: lib/who_need_help_web/live/request_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All categories"
|
msgid "All categories"
|
||||||
msgstr "Все категории"
|
msgstr "Все категории"
|
||||||
|
|
@ -263,7 +263,7 @@ msgstr "Уже зарегистрированы?"
|
||||||
msgid "Another helper already accepted this request."
|
msgid "Another helper already accepted this request."
|
||||||
msgstr "Другой помощник уже принял эту заявку."
|
msgstr "Другой помощник уже принял эту заявку."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:422
|
#: lib/who_need_help_web/live/request_live/index.ex:508
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Any urgency"
|
msgid "Any urgency"
|
||||||
msgstr "Любая срочность"
|
msgstr "Любая срочность"
|
||||||
|
|
@ -383,16 +383,16 @@ msgstr "Отменить активность"
|
||||||
msgid "Cancel request"
|
msgid "Cancel request"
|
||||||
msgstr "Отменить заявку"
|
msgstr "Отменить заявку"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:358
|
#: lib/who_need_help_web/live/activity_live/index.ex:422
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:327
|
#: lib/who_need_help_web/live/request_live/index.ex:413
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:328
|
#: lib/who_need_help_web/live/request_live/index.ex:414
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:956
|
#: lib/who_need_help_web/live/request_live/show.ex:956
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancelled"
|
msgid "Cancelled"
|
||||||
msgstr "Отменено"
|
msgstr "Отменено"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:405
|
#: lib/who_need_help_web/live/request_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:302
|
#: lib/who_need_help_web/live/request_live/new.ex:302
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
|
|
@ -476,7 +476,7 @@ msgstr "Закрыть"
|
||||||
msgid "Coffee and conversation"
|
msgid "Coffee and conversation"
|
||||||
msgstr "Кофе и разговоры"
|
msgstr "Кофе и разговоры"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:372
|
#: lib/who_need_help_web/live/activity_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -493,19 +493,19 @@ msgstr "Комментарий (необязательно)"
|
||||||
msgid "Community helpers"
|
msgid "Community helpers"
|
||||||
msgstr "Помощники сообщества"
|
msgstr "Помощники сообщества"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:578
|
#: lib/who_need_help_web/live/activity_live/index.ex:647
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:565
|
#: lib/who_need_help_web/live/request_live/index.ex:656
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Community member"
|
msgid "Community member"
|
||||||
msgstr "Член сообщества"
|
msgstr "Член сообщества"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:357
|
#: lib/who_need_help_web/live/activity_live/index.ex:421
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:325
|
#: lib/who_need_help_web/live/request_live/index.ex:411
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:326
|
#: lib/who_need_help_web/live/request_live/index.ex:412
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:955
|
#: lib/who_need_help_web/live/request_live/show.ex:955
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:974
|
#: lib/who_need_help_web/live/request_live/show.ex:974
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -558,13 +558,13 @@ msgstr "Инструкции по подтверждению"
|
||||||
msgid "Confirming..."
|
msgid "Confirming..."
|
||||||
msgstr "Подтверждение…"
|
msgstr "Подтверждение…"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:378
|
#: lib/who_need_help_web/live/activity_live/index.ex:442
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create activity"
|
msgid "Create activity"
|
||||||
msgstr "Создать активность"
|
msgstr "Создать активность"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:650
|
#: lib/who_need_help_web/live/activity_live/index.ex:722
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create an activity"
|
msgid "Create an activity"
|
||||||
|
|
@ -575,7 +575,7 @@ msgstr "Создать активность"
|
||||||
msgid "Create category"
|
msgid "Create category"
|
||||||
msgstr "Создать категорию"
|
msgstr "Создать категорию"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:356
|
#: lib/who_need_help_web/live/request_live/index.ex:442
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create urgent request"
|
msgid "Create urgent request"
|
||||||
msgstr "Создать срочную заявку"
|
msgstr "Создать срочную заявку"
|
||||||
|
|
@ -737,7 +737,7 @@ msgstr "Истекает:"
|
||||||
msgid "Explain what is already arranged and what the volunteer needs to do."
|
msgid "Explain what is already arranged and what the volunteer needs to do."
|
||||||
msgstr "Объясните, что уже сделано и что нужно сделать волонтеру."
|
msgstr "Объясните, что уже сделано и что нужно сделать волонтеру."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:369
|
#: lib/who_need_help_web/live/activity_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Find people to join"
|
msgid "Find people to join"
|
||||||
msgstr "Найти компанию"
|
msgstr "Найти компанию"
|
||||||
|
|
@ -938,8 +938,8 @@ msgstr ""
|
||||||
"Android показывает постоянное уведомление и может продолжать передачу после "
|
"Android показывает постоянное уведомление и может продолжать передачу после "
|
||||||
"сворачивания. При остановке передачи исходные координаты удаляются."
|
"сворачивания. При остановке передачи исходные координаты удаляются."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:323
|
#: lib/who_need_help_web/live/request_live/index.ex:409
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:324
|
#: lib/who_need_help_web/live/request_live/index.ex:410
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:954
|
#: lib/who_need_help_web/live/request_live/show.ex:954
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "In progress"
|
msgid "In progress"
|
||||||
|
|
@ -1069,8 +1069,8 @@ msgstr "Отметить завершённой"
|
||||||
msgid "Match and coordinate"
|
msgid "Match and coordinate"
|
||||||
msgstr "Найдите помощника и согласуйте детали"
|
msgstr "Найдите помощника и согласуйте детали"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:321
|
#: lib/who_need_help_web/live/request_live/index.ex:407
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:322
|
#: lib/who_need_help_web/live/request_live/index.ex:408
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:952
|
#: lib/who_need_help_web/live/request_live/show.ex:952
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Matched"
|
msgid "Matched"
|
||||||
|
|
@ -1099,7 +1099,7 @@ msgstr ""
|
||||||
msgid "Medicine requests"
|
msgid "Medicine requests"
|
||||||
msgstr "Заявки на лекарства"
|
msgstr "Заявки на лекарства"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:385
|
#: lib/who_need_help_web/live/activity_live/index.ex:449
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1153,12 +1153,12 @@ msgstr "Модератор"
|
||||||
msgid "Moderator access is required."
|
msgid "Moderator access is required."
|
||||||
msgstr "Требуется доступ модератора."
|
msgstr "Требуется доступ модератора."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:347
|
#: lib/who_need_help_web/live/request_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "NEARBY MUTUAL AID"
|
msgid "NEARBY MUTUAL AID"
|
||||||
msgstr "ВЗАИМОПОМОЩЬ РЯДОМ"
|
msgstr "ВЗАИМОПОМОЩЬ РЯДОМ"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:34
|
#: lib/who_need_help_web/live/request_live/index.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby help"
|
msgid "Nearby help"
|
||||||
msgstr "Помощь рядом"
|
msgstr "Помощь рядом"
|
||||||
|
|
@ -1241,9 +1241,9 @@ msgid "Not for emergencies"
|
||||||
msgstr "Не для чрезвычайных ситуаций"
|
msgstr "Не для чрезвычайных ситуаций"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:748
|
#: lib/who_need_help_web/live/notification_live.ex:748
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:311
|
#: lib/who_need_help_web/live/request_live/index.ex:397
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:312
|
#: lib/who_need_help_web/live/request_live/index.ex:398
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:423
|
#: lib/who_need_help_web/live/request_live/index.ex:509
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:449
|
#: lib/who_need_help_web/live/request_live/new.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:943
|
#: lib/who_need_help_web/live/request_live/show.ex:943
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:944
|
#: lib/who_need_help_web/live/request_live/show.ex:944
|
||||||
|
|
@ -1251,7 +1251,7 @@ msgstr "Не для чрезвычайных ситуаций"
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Сейчас"
|
msgstr "Сейчас"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:367
|
#: lib/who_need_help_web/live/activity_live/index.ex:431
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "OPTIONAL SOCIAL PLANS"
|
msgid "OPTIONAL SOCIAL PLANS"
|
||||||
msgstr "НЕОБЯЗАТЕЛЬНЫЕ СОВМЕСТНЫЕ ПЛАНЫ"
|
msgstr "НЕОБЯЗАТЕЛЬНЫЕ СОВМЕСТНЫЕ ПЛАНЫ"
|
||||||
|
|
@ -1271,12 +1271,12 @@ msgstr ""
|
||||||
#: lib/who_need_help/notifications/text.ex:140
|
#: lib/who_need_help/notifications/text.ex:140
|
||||||
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
||||||
#: lib/who_need_help_web/controllers/support_html.ex:16
|
#: lib/who_need_help_web/controllers/support_html.ex:16
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:356
|
#: lib/who_need_help_web/live/activity_live/index.ex:420
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:258
|
#: lib/who_need_help_web/live/moderation_live.ex:258
|
||||||
#: lib/who_need_help_web/live/report_live.ex:104
|
#: lib/who_need_help_web/live/report_live.ex:104
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:319
|
#: lib/who_need_help_web/live/request_live/index.ex:405
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:320
|
#: lib/who_need_help_web/live/request_live/index.ex:406
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:951
|
#: lib/who_need_help_web/live/request_live/show.ex:951
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
||||||
|
|
@ -1748,9 +1748,9 @@ msgid "Save profile"
|
||||||
msgstr "Сохранить профиль"
|
msgstr "Сохранить профиль"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:750
|
#: lib/who_need_help_web/live/notification_live.ex:750
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:315
|
#: lib/who_need_help_web/live/request_live/index.ex:401
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:316
|
#: lib/who_need_help_web/live/request_live/index.ex:402
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:425
|
#: lib/who_need_help_web/live/request_live/index.ex:511
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:451
|
#: lib/who_need_help_web/live/request_live/new.ex:451
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:947
|
#: lib/who_need_help_web/live/request_live/show.ex:947
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:948
|
#: lib/who_need_help_web/live/request_live/show.ex:948
|
||||||
|
|
@ -2022,7 +2022,7 @@ msgstr "Состояние этой активности уже изменило
|
||||||
msgid "This interaction is blocked."
|
msgid "This interaction is blocked."
|
||||||
msgstr "Это взаимодействие заблокировано."
|
msgstr "Это взаимодействие заблокировано."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:363
|
#: lib/who_need_help_web/live/request_live/index.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
||||||
|
|
@ -2075,9 +2075,9 @@ msgid "To see sent emails, visit"
|
||||||
msgstr "Чтобы посмотреть отправленные письма, откройте"
|
msgstr "Чтобы посмотреть отправленные письма, откройте"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:749
|
#: lib/who_need_help_web/live/notification_live.ex:749
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:313
|
#: lib/who_need_help_web/live/request_live/index.ex:399
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:314
|
#: lib/who_need_help_web/live/request_live/index.ex:400
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:424
|
#: lib/who_need_help_web/live/request_live/index.ex:510
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:450
|
#: lib/who_need_help_web/live/request_live/new.ex:450
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:945
|
#: lib/who_need_help_web/live/request_live/show.ex:945
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:946
|
#: lib/who_need_help_web/live/request_live/show.ex:946
|
||||||
|
|
@ -2152,7 +2152,7 @@ msgid "Update email instructions"
|
||||||
msgstr "Инструкции для изменения электронной почты"
|
msgstr "Инструкции для изменения электронной почты"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:743
|
#: lib/who_need_help_web/live/notification_live.ex:743
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:420
|
#: lib/who_need_help_web/live/request_live/index.ex:506
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:447
|
#: lib/who_need_help_web/live/request_live/new.ex:447
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Urgency"
|
msgid "Urgency"
|
||||||
|
|
@ -2308,7 +2308,7 @@ msgstr ""
|
||||||
"через подписку ChatGPT разработчика. Ключ OpenAI API и резервный вариант API"
|
"через подписку ChatGPT разработчика. Ключ OpenAI API и резервный вариант API"
|
||||||
" с оплатой по использованию не применяются."
|
" с оплатой по использованию не применяются."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:348
|
#: lib/who_need_help_web/live/request_live/index.ex:434
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Who needs help?"
|
msgid "Who needs help?"
|
||||||
msgstr "Кому нужна помощь?"
|
msgstr "Кому нужна помощь?"
|
||||||
|
|
@ -2432,7 +2432,7 @@ msgid "Your review is revealed only after both participants submit."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ваш отзыв откроется только после того, как его отправят оба участника."
|
"Ваш отзыв откроется только после того, как его отправят оба участника."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:630
|
#: lib/who_need_help_web/live/request_live/index.ex:724
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your trust summary"
|
msgid "Your trust summary"
|
||||||
msgstr "Ваши показатели доверия"
|
msgstr "Ваши показатели доверия"
|
||||||
|
|
@ -2453,17 +2453,17 @@ msgstr "сообщение активности"
|
||||||
msgid "before confirming."
|
msgid "before confirming."
|
||||||
msgstr "перед подтверждением."
|
msgstr "перед подтверждением."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:577
|
#: lib/who_need_help_web/live/activity_live/index.ex:646
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:372
|
#: lib/who_need_help_web/live/moderation_live.ex:372
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:564
|
#: lib/who_need_help_web/live/request_live/index.ex:655
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "by %{name}"
|
msgid "by %{name}"
|
||||||
msgstr "автор: %{name}"
|
msgstr "автор: %{name}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:190
|
#: lib/who_need_help_web/live/profile_live.ex:190
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:634
|
#: lib/who_need_help_web/live/request_live/index.ex:728
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "completed"
|
msgid "completed"
|
||||||
|
|
@ -2499,7 +2499,7 @@ msgstr "организатор"
|
||||||
msgid "participants only"
|
msgid "participants only"
|
||||||
msgstr "только участники"
|
msgstr "только участники"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:638
|
#: lib/who_need_help_web/live/request_live/index.ex:732
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "people"
|
msgid "people"
|
||||||
|
|
@ -2559,7 +2559,7 @@ msgstr "срочно"
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:285
|
#: lib/who_need_help_web/live/profile_live.ex:285
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:642
|
#: lib/who_need_help_web/live/request_live/index.ex:736
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2592,8 +2592,8 @@ msgstr "← Заявки"
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Одобрено"
|
msgstr "Одобрено"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:329
|
#: lib/who_need_help_web/live/request_live/index.ex:415
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:330
|
#: lib/who_need_help_web/live/request_live/index.ex:416
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr "Истекло"
|
msgstr "Истекло"
|
||||||
|
|
@ -2646,8 +2646,8 @@ msgstr "Необычная частота действий"
|
||||||
msgid "Load earlier messages"
|
msgid "Load earlier messages"
|
||||||
msgstr "Загрузить предыдущие сообщения"
|
msgstr "Загрузить предыдущие сообщения"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:589
|
#: lib/who_need_help_web/live/activity_live/index.ex:658
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
#: lib/who_need_help_web/live/activity_live/index.ex:751
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
||||||
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:465
|
#: lib/who_need_help_web/live/moderation_live.ex:465
|
||||||
|
|
@ -2659,7 +2659,7 @@ msgstr "Загрузить предыдущие сообщения"
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:363
|
#: lib/who_need_help_web/live/profile_live.ex:363
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
||||||
#: lib/who_need_help_web/live/report_live.ex:98
|
#: lib/who_need_help_web/live/report_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:699
|
#: lib/who_need_help_web/live/request_live/index.ex:805
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2667,7 +2667,7 @@ msgid "Load more"
|
||||||
msgstr "Загрузить ещё"
|
msgstr "Загрузить ещё"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:610
|
#: lib/who_need_help_web/live/request_live/index.ex:701
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Request details remain usable."
|
msgid "The map is unavailable in this browser. Request details remain usable."
|
||||||
|
|
@ -4656,7 +4656,7 @@ msgstr "Перетащите, чтобы переместить точную т
|
||||||
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
||||||
msgstr "Точная точка выбрана. Перетащите красный маркер или нажмите на карту, чтобы переместить её."
|
msgstr "Точная точка выбрана. Перетащите красный маркер или нажмите на карту, чтобы переместить её."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:453
|
#: lib/who_need_help_web/live/request_live/index.ex:539
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} request in this map area"
|
msgid "%{count} request in this map area"
|
||||||
msgid_plural "%{count} requests in this map area"
|
msgid_plural "%{count} requests in this map area"
|
||||||
|
|
@ -4664,37 +4664,37 @@ msgstr[0] "%{count} заявка в этой области карты"
|
||||||
msgstr[1] "%{count} заявки в этой области карты"
|
msgstr[1] "%{count} заявки в этой области карты"
|
||||||
msgstr[2] "%{count} заявок в этой области карты"
|
msgstr[2] "%{count} заявок в этой области карты"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:438
|
#: lib/who_need_help_web/live/activity_live/index.ex:502
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:430
|
#: lib/who_need_help_web/live/request_live/index.ex:516
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Area or city"
|
msgid "Area or city"
|
||||||
msgstr "Район или город"
|
msgstr "Район или город"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:525
|
#: lib/who_need_help_web/live/activity_live/index.ex:594
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:515
|
#: lib/who_need_help_web/live/request_live/index.ex:606
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Choose an area on the map"
|
msgid "Choose an area on the map"
|
||||||
msgstr "Выберите область на карте"
|
msgstr "Выберите область на карте"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:350
|
#: lib/who_need_help_web/live/request_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
||||||
msgstr "Просматривайте безопасные для приватности области и точные публичные места встречи, выбранные авторами заявок."
|
msgstr "Просматривайте безопасные для приватности области и точные публичные места встречи, выбранные авторами заявок."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:484
|
#: lib/who_need_help_web/live/activity_live/index.ex:553
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:474
|
#: lib/who_need_help_web/live/request_live/index.ex:565
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "List"
|
msgid "List"
|
||||||
msgstr "Список"
|
msgstr "Список"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:586
|
#: lib/who_need_help_web/live/request_live/index.ex:677
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Load more in this area"
|
msgid "Load more in this area"
|
||||||
msgstr "Загрузить ещё в этой области"
|
msgstr "Загрузить ещё в этой области"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:504
|
#: lib/who_need_help_web/live/activity_live/index.ex:573
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:494
|
#: lib/who_need_help_web/live/request_live/index.ex:585
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Map"
|
msgid "Map"
|
||||||
msgstr "Карта"
|
msgstr "Карта"
|
||||||
|
|
@ -4704,53 +4704,53 @@ msgstr "Карта"
|
||||||
msgid "Map preview"
|
msgid "Map preview"
|
||||||
msgstr "Предпросмотр карты"
|
msgstr "Предпросмотр карты"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:537
|
#: lib/who_need_help_web/live/activity_live/index.ex:606
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:527
|
#: lib/who_need_help_web/live/request_live/index.ex:618
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move or zoom the map to search somewhere else."
|
msgid "Move or zoom the map to search somewhere else."
|
||||||
msgstr "Переместите или масштабируйте карту, чтобы искать в другом месте."
|
msgstr "Переместите или масштабируйте карту, чтобы искать в другом месте."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:471
|
#: lib/who_need_help_web/live/activity_live/index.ex:540
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:461
|
#: lib/who_need_help_web/live/request_live/index.ex:552
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move the map, then search the newly visible area."
|
msgid "Move the map, then search the newly visible area."
|
||||||
msgstr "Переместите карту, затем выполните поиск в новой видимой области."
|
msgstr "Переместите карту, затем выполните поиск в новой видимой области."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:525
|
#: lib/who_need_help_web/live/request_live/index.ex:616
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open requests in this area"
|
msgid "No open requests in this area"
|
||||||
msgstr "В этой области нет открытых заявок"
|
msgstr "В этой области нет открытых заявок"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:517
|
#: lib/who_need_help_web/live/request_live/index.ex:608
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only requests from the selected map area will be loaded."
|
msgid "Only requests from the selected map area will be loaded."
|
||||||
msgstr "Будут загружены только заявки из выбранной области карты."
|
msgstr "Будут загружены только заявки из выбранной области карты."
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:613
|
#: lib/who_need_help_web/live/request_live/index.ex:704
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open request"
|
msgid "Open request"
|
||||||
msgstr "Открыть заявку"
|
msgstr "Открыть заявку"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:439
|
#: lib/who_need_help_web/live/activity_live/index.ex:503
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:431
|
#: lib/who_need_help_web/live/request_live/index.ex:517
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Optional text search"
|
msgid "Optional text search"
|
||||||
msgstr "Необязательный текстовый поиск"
|
msgstr "Необязательный текстовый поиск"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:592
|
#: lib/who_need_help_web/live/request_live/index.ex:683
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
||||||
msgstr "Заявки без координат на карте отображаются только тогда, когда описание публичной области совпадает с текстовым поиском."
|
msgstr "Заявки без координат на карте отображаются только тогда, когда описание публичной области совпадает с текстовым поиском."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:475
|
#: lib/who_need_help_web/live/activity_live/index.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:465
|
#: lib/who_need_help_web/live/request_live/index.ex:556
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Results layout"
|
msgid "Results layout"
|
||||||
msgstr "Расположение результатов"
|
msgstr "Расположение результатов"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:621
|
#: lib/who_need_help_web/live/activity_live/index.ex:693
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:625
|
#: lib/who_need_help_web/live/request_live/index.ex:719
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search this area"
|
msgid "Search this area"
|
||||||
msgstr "Искать в этой области"
|
msgstr "Искать в этой области"
|
||||||
|
|
@ -4760,21 +4760,21 @@ msgstr "Искать в этой области"
|
||||||
msgid "Static preview"
|
msgid "Static preview"
|
||||||
msgstr "Статический просмотр"
|
msgstr "Статический просмотр"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:494
|
#: lib/who_need_help_web/live/activity_live/index.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:484
|
#: lib/who_need_help_web/live/request_live/index.ex:575
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Together"
|
msgid "Together"
|
||||||
msgstr "Вместе"
|
msgstr "Вместе"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
||||||
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:609
|
#: lib/who_need_help_web/live/activity_live/index.ex:681
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:602
|
#: lib/who_need_help_web/live/notification_live.ex:602
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:621
|
#: lib/who_need_help_web/live/notification_live.ex:621
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:612
|
#: lib/who_need_help_web/live/request_live/index.ex:703
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:485
|
#: lib/who_need_help_web/live/request_live/new.ex:485
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:563
|
#: lib/who_need_help_web/live/request_live/new.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
||||||
|
|
@ -5164,7 +5164,7 @@ msgid "Nearby alert deleted."
|
||||||
msgstr "Уведомление поблизости удалено."
|
msgstr "Уведомление поблизости удалено."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:456
|
#: lib/who_need_help_web/live/notification_live.ex:456
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:376
|
#: lib/who_need_help_web/live/request_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby requests"
|
msgid "Nearby requests"
|
||||||
msgstr "Заявки поблизости"
|
msgstr "Заявки поблизости"
|
||||||
|
|
@ -5504,7 +5504,7 @@ msgid "WebGL is unavailable in this browser, so the full map cannot start. Selec
|
||||||
msgstr "WebGL недоступен в этом браузере, поэтому полная карта не может запуститься. Выберите пример ниже или попробуйте запустить карту ещё раз."
|
msgstr "WebGL недоступен в этом браузере, поэтому полная карта не может запуститься. Выберите пример ниже или попробуйте запустить карту ещё раз."
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:610
|
#: lib/who_need_help_web/live/activity_live/index.ex:682
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -6069,7 +6069,7 @@ msgstr "Теперь ваш отзыв виден"
|
||||||
msgid "Delivery settings"
|
msgid "Delivery settings"
|
||||||
msgstr "Настройки доставки"
|
msgstr "Настройки доставки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:569
|
#: lib/who_need_help_web/live/request_live/index.ex:660
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expires"
|
msgid "Expires"
|
||||||
msgstr "Истекает"
|
msgstr "Истекает"
|
||||||
|
|
@ -6089,12 +6089,12 @@ msgstr "Оповещения рядом"
|
||||||
msgid "Notification sections"
|
msgid "Notification sections"
|
||||||
msgstr "Разделы уведомлений"
|
msgstr "Разделы уведомлений"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:605
|
#: lib/who_need_help_web/live/activity_live/index.ex:674
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activities"
|
msgid "%{count} activities"
|
||||||
msgstr "Активностей: %{count}"
|
msgstr "Активностей: %{count}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activity in this map area"
|
msgid "%{count} activity in this map area"
|
||||||
msgid_plural "%{count} activities in this map area"
|
msgid_plural "%{count} activities in this map area"
|
||||||
|
|
@ -6102,17 +6102,17 @@ msgstr[0] "%{count} активность в этой области карты"
|
||||||
msgstr[1] "%{count} активности в этой области карты"
|
msgstr[1] "%{count} активности в этой области карты"
|
||||||
msgstr[2] "%{count} активностей в этой области карты"
|
msgstr[2] "%{count} активностей в этой области карты"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:614
|
#: lib/who_need_help_web/live/request_live/index.ex:705
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} requests"
|
msgid "%{count} requests"
|
||||||
msgstr "Заявок: %{count}"
|
msgstr "Заявок: %{count}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:645
|
#: lib/who_need_help_web/live/activity_live/index.ex:717
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
||||||
msgstr "Созданные вами активности и те, к которым вы попросили присоединиться, появятся здесь. После выхода активность исчезнет из списка."
|
msgstr "Созданные вами активности и те, к которым вы попросили присоединиться, появятся здесь. После выхода активность исчезнет из списка."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:393
|
#: lib/who_need_help_web/live/activity_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity views"
|
msgid "Activity views"
|
||||||
msgstr "Разделы активностей"
|
msgstr "Разделы активностей"
|
||||||
|
|
@ -6127,12 +6127,12 @@ msgstr "Выберите категорию и понятно опишите з
|
||||||
msgid "Confirm the safety guidance before asking nearby people for help."
|
msgid "Confirm the safety guidance before asking nearby people for help."
|
||||||
msgstr "Подтвердите правила безопасности перед публикацией заявки."
|
msgstr "Подтвердите правила безопасности перед публикацией заявки."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:659
|
#: lib/who_need_help_web/live/request_live/index.ex:753
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create request"
|
msgid "Create request"
|
||||||
msgstr "Создать заявку"
|
msgstr "Создать заявку"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:673
|
#: lib/who_need_help_web/live/request_live/index.ex:776
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create your first request"
|
msgid "Create your first request"
|
||||||
msgstr "Создать первую заявку"
|
msgstr "Создать первую заявку"
|
||||||
|
|
@ -6147,43 +6147,43 @@ msgstr "Что нужно сделать"
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Место"
|
msgstr "Место"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:399
|
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My activities"
|
msgid "My activities"
|
||||||
msgstr "Мои активности"
|
msgstr "Мои активности"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:377
|
#: lib/who_need_help_web/live/request_live/index.ex:463
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:653
|
#: lib/who_need_help_web/live/request_live/index.ex:747
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My requests"
|
msgid "My requests"
|
||||||
msgstr "Мои заявки"
|
msgstr "Мои заявки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:398
|
#: lib/who_need_help_web/live/activity_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby activities"
|
msgid "Nearby activities"
|
||||||
msgstr "Активности рядом"
|
msgstr "Активности рядом"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:643
|
#: lib/who_need_help_web/live/activity_live/index.ex:715
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No activities yet"
|
msgid "No activities yet"
|
||||||
msgstr "Активностей пока нет"
|
msgstr "Активностей пока нет"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open activities in this area"
|
msgid "No open activities in this area"
|
||||||
msgstr "В этой области нет открытых активностей"
|
msgstr "В этой области нет открытых активностей"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:668
|
#: lib/who_need_help_web/live/request_live/index.ex:771
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No requests yet"
|
msgid "No requests yet"
|
||||||
msgstr "Заявок пока нет"
|
msgstr "Заявок пока нет"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
#: lib/who_need_help_web/live/activity_live/index.ex:596
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only activities from the selected map area will be loaded."
|
msgid "Only activities from the selected map area will be loaded."
|
||||||
msgstr "Будут загружены только активности из выбранной области карты."
|
msgstr "Будут загружены только активности из выбранной области карты."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
#: lib/who_need_help_web/live/activity_live/index.ex:673
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open activity"
|
msgid "Open activity"
|
||||||
msgstr "Открыть активность"
|
msgstr "Открыть активность"
|
||||||
|
|
@ -6193,12 +6193,12 @@ msgstr "Открыть активность"
|
||||||
msgid "Request form steps"
|
msgid "Request form steps"
|
||||||
msgstr "Шаги создания заявки"
|
msgstr "Шаги создания заявки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:371
|
#: lib/who_need_help_web/live/request_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Request views"
|
msgid "Request views"
|
||||||
msgstr "Разделы заявок"
|
msgstr "Разделы заявок"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:670
|
#: lib/who_need_help_web/live/request_live/index.ex:773
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests you publish or accept will appear here."
|
msgid "Requests you publish or accept will appear here."
|
||||||
msgstr "Здесь появятся заявки, которые вы создали или приняли."
|
msgstr "Здесь появятся заявки, которые вы создали или приняли."
|
||||||
|
|
@ -6223,7 +6223,7 @@ msgstr "Укажите срочность и время закрытия зая
|
||||||
msgid "Share only as much location detail as helpers need."
|
msgid "Share only as much location detail as helpers need."
|
||||||
msgstr "Покажите помощникам только необходимую информацию о месте."
|
msgstr "Покажите помощникам только необходимую информацию о месте."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:607
|
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Activity details remain usable."
|
msgid "The map is unavailable in this browser. Activity details remain usable."
|
||||||
msgstr "Карта недоступна в этом браузере. Информация об активностях по-прежнему доступна."
|
msgstr "Карта недоступна в этом браузере. Информация об активностях по-прежнему доступна."
|
||||||
|
|
@ -6233,7 +6233,7 @@ msgstr "Карта недоступна в этом браузере. Инфор
|
||||||
msgid "Timing"
|
msgid "Timing"
|
||||||
msgstr "Время"
|
msgstr "Время"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:655
|
#: lib/who_need_help_web/live/request_live/index.ex:749
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Track requests you created and requests you accepted as a helper."
|
msgid "Track requests you created and requests you accepted as a helper."
|
||||||
msgstr "Следите за созданными заявками и за теми, которые вы приняли как помощник."
|
msgstr "Следите за созданными заявками и за теми, которые вы приняли как помощник."
|
||||||
|
|
@ -6894,11 +6894,32 @@ msgstr "Что должны видеть люди до одобрения?"
|
||||||
msgid "Choose the meeting point on the map or use your current location."
|
msgid "Choose the meeting point on the map or use your current location."
|
||||||
msgstr "Выберите место встречи на карте или используйте своё текущее местоположение."
|
msgstr "Выберите место встречи на карте или используйте своё текущее местоположение."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:458
|
#: lib/who_need_help_web/live/activity_live/index.ex:522
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:517
|
#: lib/who_need_help_web/live/activity_live/index.ex:586
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:635
|
#: lib/who_need_help_web/live/activity_live/index.ex:707
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:448
|
#: lib/who_need_help_web/live/request_live/index.ex:534
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:507
|
#: lib/who_need_help_web/live/request_live/index.ex:598
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:763
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loading results…"
|
msgid "Loading results…"
|
||||||
msgstr "Загружаем результаты…"
|
msgstr "Загружаем результаты…"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:676
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching activities are listed beside the map."
|
||||||
|
msgstr "Достигнут максимальный масштаб. Подходящие мероприятия перечислены рядом с картой."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:707
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching requests are listed beside the map."
|
||||||
|
msgstr "Достигнут максимальный масштаб. Подходящие заявки перечислены рядом с картой."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching activities with map locations"
|
||||||
|
msgstr "из %{count} подходящих мероприятий с местоположением на карте"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:547
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching requests with map locations"
|
||||||
|
msgstr "из %{count} подходящих заявок с местоположением на карте"
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ msgid "Active"
|
||||||
msgstr "Активний"
|
msgstr "Активний"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:231
|
#: lib/who_need_help_web/components/layouts.ex:231
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:33
|
#: lib/who_need_help_web/live/activity_live/index.ex:37
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Активності"
|
msgstr "Активності"
|
||||||
|
|
@ -226,7 +226,7 @@ msgstr "Активність опубліковано. Ви схвалюєте
|
||||||
msgid "Activity restored."
|
msgid "Activity restored."
|
||||||
msgstr "Активність відновлено."
|
msgstr "Активність відновлено."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:427
|
#: lib/who_need_help_web/live/activity_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
#: lib/who_need_help_web/live/activity_live/new.ex:204
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity type"
|
msgid "Activity type"
|
||||||
|
|
@ -243,12 +243,12 @@ msgstr "Додати непідтверджене посилання"
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Адміністратор"
|
msgstr "Адміністратор"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:429
|
#: lib/who_need_help_web/live/activity_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All activities"
|
msgid "All activities"
|
||||||
msgstr "Усі активності"
|
msgstr "Усі активності"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:407
|
#: lib/who_need_help_web/live/request_live/index.ex:493
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "All categories"
|
msgid "All categories"
|
||||||
msgstr "Усі категорії"
|
msgstr "Усі категорії"
|
||||||
|
|
@ -263,7 +263,7 @@ msgstr "Уже зареєстровані?"
|
||||||
msgid "Another helper already accepted this request."
|
msgid "Another helper already accepted this request."
|
||||||
msgstr "Інший помічник уже прийняв цю заявку."
|
msgstr "Інший помічник уже прийняв цю заявку."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:422
|
#: lib/who_need_help_web/live/request_live/index.ex:508
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Any urgency"
|
msgid "Any urgency"
|
||||||
msgstr "Будь-яка терміновість"
|
msgstr "Будь-яка терміновість"
|
||||||
|
|
@ -383,16 +383,16 @@ msgstr "Скасувати активність"
|
||||||
msgid "Cancel request"
|
msgid "Cancel request"
|
||||||
msgstr "Скасувати запит"
|
msgstr "Скасувати запит"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:358
|
#: lib/who_need_help_web/live/activity_live/index.ex:422
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
#: lib/who_need_help_web/live/activity_live/show.ex:344
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:327
|
#: lib/who_need_help_web/live/request_live/index.ex:413
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:328
|
#: lib/who_need_help_web/live/request_live/index.ex:414
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:956
|
#: lib/who_need_help_web/live/request_live/show.ex:956
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancelled"
|
msgid "Cancelled"
|
||||||
msgstr "Скасовано"
|
msgstr "Скасовано"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:405
|
#: lib/who_need_help_web/live/request_live/index.ex:491
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:302
|
#: lib/who_need_help_web/live/request_live/new.ex:302
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
|
|
@ -476,7 +476,7 @@ msgstr "Закрити"
|
||||||
msgid "Coffee and conversation"
|
msgid "Coffee and conversation"
|
||||||
msgstr "Кава й розмова"
|
msgstr "Кава й розмова"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:372
|
#: lib/who_need_help_web/live/activity_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
msgid "Coffee, cinema, walks, and hikes are separate from urgent help and never affect helper ratings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -493,19 +493,19 @@ msgstr "Коментар (необов’язково)"
|
||||||
msgid "Community helpers"
|
msgid "Community helpers"
|
||||||
msgstr "Помічники спільноти"
|
msgstr "Помічники спільноти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:578
|
#: lib/who_need_help_web/live/activity_live/index.ex:647
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
#: lib/who_need_help_web/live/activity_live/show.ex:403
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
#: lib/who_need_help_web/live/activity_live/show.ex:639
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
#: lib/who_need_help_web/live/activity_live/show.ex:698
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:565
|
#: lib/who_need_help_web/live/request_live/index.ex:656
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Community member"
|
msgid "Community member"
|
||||||
msgstr "Член спільноти"
|
msgstr "Член спільноти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:357
|
#: lib/who_need_help_web/live/activity_live/index.ex:421
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
#: lib/who_need_help_web/live/activity_live/show.ex:343
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:325
|
#: lib/who_need_help_web/live/request_live/index.ex:411
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:326
|
#: lib/who_need_help_web/live/request_live/index.ex:412
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:955
|
#: lib/who_need_help_web/live/request_live/show.ex:955
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:974
|
#: lib/who_need_help_web/live/request_live/show.ex:974
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -559,13 +559,13 @@ msgstr "Інструкції для підтвердження"
|
||||||
msgid "Confirming..."
|
msgid "Confirming..."
|
||||||
msgstr "Підтвердження…"
|
msgstr "Підтвердження…"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:378
|
#: lib/who_need_help_web/live/activity_live/index.ex:442
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
#: lib/who_need_help_web/live/activity_live/new.ex:12
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create activity"
|
msgid "Create activity"
|
||||||
msgstr "Створити активність"
|
msgstr "Створити активність"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:650
|
#: lib/who_need_help_web/live/activity_live/index.ex:722
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
#: lib/who_need_help_web/live/activity_live/new.ex:180
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create an activity"
|
msgid "Create an activity"
|
||||||
|
|
@ -576,7 +576,7 @@ msgstr "Створити активність"
|
||||||
msgid "Create category"
|
msgid "Create category"
|
||||||
msgstr "Створити категорію"
|
msgstr "Створити категорію"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:356
|
#: lib/who_need_help_web/live/request_live/index.ex:442
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create urgent request"
|
msgid "Create urgent request"
|
||||||
msgstr "Створити термінову заявку"
|
msgstr "Створити термінову заявку"
|
||||||
|
|
@ -736,7 +736,7 @@ msgstr "Спливає:"
|
||||||
msgid "Explain what is already arranged and what the volunteer needs to do."
|
msgid "Explain what is already arranged and what the volunteer needs to do."
|
||||||
msgstr "Поясніть, що вже організовано й що має зробити волонтер."
|
msgstr "Поясніть, що вже організовано й що має зробити волонтер."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:369
|
#: lib/who_need_help_web/live/activity_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Find people to join"
|
msgid "Find people to join"
|
||||||
msgstr "Знайти компанію"
|
msgstr "Знайти компанію"
|
||||||
|
|
@ -936,8 +936,8 @@ msgstr ""
|
||||||
"Android показує постійне сповіщення й може продовжувати передавання після "
|
"Android показує постійне сповіщення й може продовжувати передавання після "
|
||||||
"згортання. Після зупинення передавання вихідні координати видаляються."
|
"згортання. Після зупинення передавання вихідні координати видаляються."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:323
|
#: lib/who_need_help_web/live/request_live/index.ex:409
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:324
|
#: lib/who_need_help_web/live/request_live/index.ex:410
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:954
|
#: lib/who_need_help_web/live/request_live/show.ex:954
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "In progress"
|
msgid "In progress"
|
||||||
|
|
@ -1065,8 +1065,8 @@ msgstr "Позначити завершеною"
|
||||||
msgid "Match and coordinate"
|
msgid "Match and coordinate"
|
||||||
msgstr "Знайдіть помічника й узгодьте деталі"
|
msgstr "Знайдіть помічника й узгодьте деталі"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:321
|
#: lib/who_need_help_web/live/request_live/index.ex:407
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:322
|
#: lib/who_need_help_web/live/request_live/index.ex:408
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:952
|
#: lib/who_need_help_web/live/request_live/show.ex:952
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Matched"
|
msgid "Matched"
|
||||||
|
|
@ -1095,7 +1095,7 @@ msgstr ""
|
||||||
msgid "Medicine requests"
|
msgid "Medicine requests"
|
||||||
msgstr "Запити на ліки"
|
msgstr "Запити на ліки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:385
|
#: lib/who_need_help_web/live/activity_live/index.ex:449
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
msgid "Meet in public first, keep exact details inside the approved group, and leave or report anything that feels unsafe."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1149,12 +1149,12 @@ msgstr "Модератор"
|
||||||
msgid "Moderator access is required."
|
msgid "Moderator access is required."
|
||||||
msgstr "Потрібен доступ модератора."
|
msgstr "Потрібен доступ модератора."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:347
|
#: lib/who_need_help_web/live/request_live/index.ex:433
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "NEARBY MUTUAL AID"
|
msgid "NEARBY MUTUAL AID"
|
||||||
msgstr "ВЗАЄМОДОПОМОГА ПОРУЧ"
|
msgstr "ВЗАЄМОДОПОМОГА ПОРУЧ"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:34
|
#: lib/who_need_help_web/live/request_live/index.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby help"
|
msgid "Nearby help"
|
||||||
msgstr "Допомога поруч"
|
msgstr "Допомога поруч"
|
||||||
|
|
@ -1237,9 +1237,9 @@ msgid "Not for emergencies"
|
||||||
msgstr "Не для екстрених ситуацій"
|
msgstr "Не для екстрених ситуацій"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:748
|
#: lib/who_need_help_web/live/notification_live.ex:748
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:311
|
#: lib/who_need_help_web/live/request_live/index.ex:397
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:312
|
#: lib/who_need_help_web/live/request_live/index.ex:398
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:423
|
#: lib/who_need_help_web/live/request_live/index.ex:509
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:449
|
#: lib/who_need_help_web/live/request_live/new.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:943
|
#: lib/who_need_help_web/live/request_live/show.ex:943
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:944
|
#: lib/who_need_help_web/live/request_live/show.ex:944
|
||||||
|
|
@ -1247,7 +1247,7 @@ msgstr "Не для екстрених ситуацій"
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Зараз"
|
msgstr "Зараз"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:367
|
#: lib/who_need_help_web/live/activity_live/index.ex:431
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "OPTIONAL SOCIAL PLANS"
|
msgid "OPTIONAL SOCIAL PLANS"
|
||||||
msgstr "НЕОБОВ’ЯЗКОВІ СПІЛЬНІ ПЛАНИ"
|
msgstr "НЕОБОВ’ЯЗКОВІ СПІЛЬНІ ПЛАНИ"
|
||||||
|
|
@ -1267,12 +1267,12 @@ msgstr ""
|
||||||
#: lib/who_need_help/notifications/text.ex:140
|
#: lib/who_need_help/notifications/text.ex:140
|
||||||
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
#: lib/who_need_help_web/controllers/content_removal_html.ex:21
|
||||||
#: lib/who_need_help_web/controllers/support_html.ex:16
|
#: lib/who_need_help_web/controllers/support_html.ex:16
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:356
|
#: lib/who_need_help_web/live/activity_live/index.ex:420
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
#: lib/who_need_help_web/live/activity_live/show.ex:342
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:258
|
#: lib/who_need_help_web/live/moderation_live.ex:258
|
||||||
#: lib/who_need_help_web/live/report_live.ex:104
|
#: lib/who_need_help_web/live/report_live.ex:104
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:319
|
#: lib/who_need_help_web/live/request_live/index.ex:405
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:320
|
#: lib/who_need_help_web/live/request_live/index.ex:406
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:951
|
#: lib/who_need_help_web/live/request_live/show.ex:951
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
#: lib/who_need_help_web/live/support_operations_live.ex:237
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
#: lib/who_need_help_web/live/support_operations_live.ex:438
|
||||||
|
|
@ -1745,9 +1745,9 @@ msgid "Save profile"
|
||||||
msgstr "Зберегти профіль"
|
msgstr "Зберегти профіль"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:750
|
#: lib/who_need_help_web/live/notification_live.ex:750
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:315
|
#: lib/who_need_help_web/live/request_live/index.ex:401
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:316
|
#: lib/who_need_help_web/live/request_live/index.ex:402
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:425
|
#: lib/who_need_help_web/live/request_live/index.ex:511
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:451
|
#: lib/who_need_help_web/live/request_live/new.ex:451
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:947
|
#: lib/who_need_help_web/live/request_live/show.ex:947
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:948
|
#: lib/who_need_help_web/live/request_live/show.ex:948
|
||||||
|
|
@ -2019,7 +2019,7 @@ msgstr "Цей стан активності вже змінено."
|
||||||
msgid "This interaction is blocked."
|
msgid "This interaction is blocked."
|
||||||
msgstr "Ця взаємодія заблокована."
|
msgstr "Ця взаємодія заблокована."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:363
|
#: lib/who_need_help_web/live/request_live/index.ex:449
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
#: lib/who_need_help_web/live/request_live/show.ex:1022
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
msgid "This is not an emergency service. Contact local emergency services for immediate danger."
|
||||||
|
|
@ -2072,9 +2072,9 @@ msgid "To see sent emails, visit"
|
||||||
msgstr "Щоб переглянути надіслані листи, відкрийте"
|
msgstr "Щоб переглянути надіслані листи, відкрийте"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:749
|
#: lib/who_need_help_web/live/notification_live.ex:749
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:313
|
#: lib/who_need_help_web/live/request_live/index.ex:399
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:314
|
#: lib/who_need_help_web/live/request_live/index.ex:400
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:424
|
#: lib/who_need_help_web/live/request_live/index.ex:510
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:450
|
#: lib/who_need_help_web/live/request_live/new.ex:450
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:945
|
#: lib/who_need_help_web/live/request_live/show.ex:945
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:946
|
#: lib/who_need_help_web/live/request_live/show.ex:946
|
||||||
|
|
@ -2149,7 +2149,7 @@ msgid "Update email instructions"
|
||||||
msgstr "Інструкції для зміни електронної пошти"
|
msgstr "Інструкції для зміни електронної пошти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:743
|
#: lib/who_need_help_web/live/notification_live.ex:743
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:420
|
#: lib/who_need_help_web/live/request_live/index.ex:506
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:447
|
#: lib/who_need_help_web/live/request_live/new.ex:447
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Urgency"
|
msgid "Urgency"
|
||||||
|
|
@ -2304,7 +2304,7 @@ msgstr ""
|
||||||
"через підписку ChatGPT розробника. Ключ OpenAI API та резервний варіант API "
|
"через підписку ChatGPT розробника. Ключ OpenAI API та резервний варіант API "
|
||||||
"з оплатою за використання не застосовуються."
|
"з оплатою за використання не застосовуються."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:348
|
#: lib/who_need_help_web/live/request_live/index.ex:434
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Who needs help?"
|
msgid "Who needs help?"
|
||||||
msgstr "Хто потребує допомоги?"
|
msgstr "Хто потребує допомоги?"
|
||||||
|
|
@ -2426,7 +2426,7 @@ msgid "Your review is revealed only after both participants submit."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ваш відгук відкриється лише після того, як його надішлють обидва учасники."
|
"Ваш відгук відкриється лише після того, як його надішлють обидва учасники."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:630
|
#: lib/who_need_help_web/live/request_live/index.ex:724
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your trust summary"
|
msgid "Your trust summary"
|
||||||
msgstr "Ваші показники довіри"
|
msgstr "Ваші показники довіри"
|
||||||
|
|
@ -2447,17 +2447,17 @@ msgstr "повідомлення активності"
|
||||||
msgid "before confirming."
|
msgid "before confirming."
|
||||||
msgstr "перед підтвердженням."
|
msgstr "перед підтвердженням."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:577
|
#: lib/who_need_help_web/live/activity_live/index.ex:646
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
#: lib/who_need_help_web/live/category_proposal_live.ex:252
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:372
|
#: lib/who_need_help_web/live/moderation_live.ex:372
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:564
|
#: lib/who_need_help_web/live/request_live/index.ex:655
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "by %{name}"
|
msgid "by %{name}"
|
||||||
msgstr "автор: %{name}"
|
msgstr "автор: %{name}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:190
|
#: lib/who_need_help_web/live/profile_live.ex:190
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
#: lib/who_need_help_web/live/public_profile_live.ex:133
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:634
|
#: lib/who_need_help_web/live/request_live/index.ex:728
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
#: lib/who_need_help_web/live/request_live/show.ex:1374
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "completed"
|
msgid "completed"
|
||||||
|
|
@ -2493,7 +2493,7 @@ msgstr "організатор"
|
||||||
msgid "participants only"
|
msgid "participants only"
|
||||||
msgstr "лише учасники"
|
msgstr "лише учасники"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:638
|
#: lib/who_need_help_web/live/request_live/index.ex:732
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
#: lib/who_need_help_web/live/request_live/show.ex:1378
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "people"
|
msgid "people"
|
||||||
|
|
@ -2553,7 +2553,7 @@ msgstr "терміново"
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
#: lib/who_need_help_web/live/activity_live/show.ex:719
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:285
|
#: lib/who_need_help_web/live/profile_live.ex:285
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
#: lib/who_need_help_web/live/public_profile_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:642
|
#: lib/who_need_help_web/live/request_live/index.ex:736
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
#: lib/who_need_help_web/live/request_live/show.ex:1093
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
#: lib/who_need_help_web/live/request_live/show.ex:1476
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2586,8 +2586,8 @@ msgstr "← Заявки"
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Схвалено"
|
msgstr "Схвалено"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:329
|
#: lib/who_need_help_web/live/request_live/index.ex:415
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:330
|
#: lib/who_need_help_web/live/request_live/index.ex:416
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr "Спливло"
|
msgstr "Спливло"
|
||||||
|
|
@ -2640,8 +2640,8 @@ msgstr "Незвична частота дій"
|
||||||
msgid "Load earlier messages"
|
msgid "Load earlier messages"
|
||||||
msgstr "Завантажити попередні повідомлення"
|
msgstr "Завантажити попередні повідомлення"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:589
|
#: lib/who_need_help_web/live/activity_live/index.ex:658
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
#: lib/who_need_help_web/live/activity_live/index.ex:751
|
||||||
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
#: lib/who_need_help_web/live/category_proposal_live.ex:284
|
||||||
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
#: lib/who_need_help_web/live/leaderboard_live.ex:91
|
||||||
#: lib/who_need_help_web/live/moderation_live.ex:465
|
#: lib/who_need_help_web/live/moderation_live.ex:465
|
||||||
|
|
@ -2653,7 +2653,7 @@ msgstr "Завантажити попередні повідомлення"
|
||||||
#: lib/who_need_help_web/live/profile_live.ex:363
|
#: lib/who_need_help_web/live/profile_live.ex:363
|
||||||
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
#: lib/who_need_help_web/live/public_profile_live.ex:178
|
||||||
#: lib/who_need_help_web/live/report_live.ex:98
|
#: lib/who_need_help_web/live/report_live.ex:98
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:699
|
#: lib/who_need_help_web/live/request_live/index.ex:805
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
#: lib/who_need_help_web/live/support_operations_live.ex:306
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
#: lib/who_need_help_web/live/support_operations_live.ex:505
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2661,7 +2661,7 @@ msgid "Load more"
|
||||||
msgstr "Завантажити ще"
|
msgstr "Завантажити ще"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
#: lib/who_need_help_web/live/activity_live/show.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:610
|
#: lib/who_need_help_web/live/request_live/index.ex:701
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
#: lib/who_need_help_web/live/request_live/show.ex:1275
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Request details remain usable."
|
msgid "The map is unavailable in this browser. Request details remain usable."
|
||||||
|
|
@ -4650,7 +4650,7 @@ msgstr "Перетягніть, щоб перемістити точну точ
|
||||||
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
msgid "Exact point selected. Drag the red pin or click the map to move it."
|
||||||
msgstr "Точну точку вибрано. Перетягніть червоний маркер або натисніть на карту, щоб перемістити її."
|
msgstr "Точну точку вибрано. Перетягніть червоний маркер або натисніть на карту, щоб перемістити її."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:453
|
#: lib/who_need_help_web/live/request_live/index.ex:539
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} request in this map area"
|
msgid "%{count} request in this map area"
|
||||||
msgid_plural "%{count} requests in this map area"
|
msgid_plural "%{count} requests in this map area"
|
||||||
|
|
@ -4658,37 +4658,37 @@ msgstr[0] "%{count} заявка в цій області карти"
|
||||||
msgstr[1] "%{count} заявки в цій області карти"
|
msgstr[1] "%{count} заявки в цій області карти"
|
||||||
msgstr[2] "%{count} заявок у цій області карти"
|
msgstr[2] "%{count} заявок у цій області карти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:438
|
#: lib/who_need_help_web/live/activity_live/index.ex:502
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:430
|
#: lib/who_need_help_web/live/request_live/index.ex:516
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Area or city"
|
msgid "Area or city"
|
||||||
msgstr "Район або місто"
|
msgstr "Район або місто"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:525
|
#: lib/who_need_help_web/live/activity_live/index.ex:594
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:515
|
#: lib/who_need_help_web/live/request_live/index.ex:606
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Choose an area on the map"
|
msgid "Choose an area on the map"
|
||||||
msgstr "Виберіть область на карті"
|
msgstr "Виберіть область на карті"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:350
|
#: lib/who_need_help_web/live/request_live/index.ex:436
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
msgid "Explore privacy-friendly areas and public exact meeting points chosen by requesters."
|
||||||
msgstr "Переглядайте приватні області та точні публічні місця зустрічі, вибрані авторами заявок."
|
msgstr "Переглядайте приватні області та точні публічні місця зустрічі, вибрані авторами заявок."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:484
|
#: lib/who_need_help_web/live/activity_live/index.ex:553
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:474
|
#: lib/who_need_help_web/live/request_live/index.ex:565
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "List"
|
msgid "List"
|
||||||
msgstr "Список"
|
msgstr "Список"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:586
|
#: lib/who_need_help_web/live/request_live/index.ex:677
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Load more in this area"
|
msgid "Load more in this area"
|
||||||
msgstr "Завантажити ще в цій області"
|
msgstr "Завантажити ще в цій області"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
#: lib/who_need_help_web/components/layouts/root.html.heex:5
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:504
|
#: lib/who_need_help_web/live/activity_live/index.ex:573
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:494
|
#: lib/who_need_help_web/live/request_live/index.ex:585
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Map"
|
msgid "Map"
|
||||||
msgstr "Карта"
|
msgstr "Карта"
|
||||||
|
|
@ -4698,53 +4698,53 @@ msgstr "Карта"
|
||||||
msgid "Map preview"
|
msgid "Map preview"
|
||||||
msgstr "Попередній перегляд карти"
|
msgstr "Попередній перегляд карти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:537
|
#: lib/who_need_help_web/live/activity_live/index.ex:606
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:527
|
#: lib/who_need_help_web/live/request_live/index.ex:618
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move or zoom the map to search somewhere else."
|
msgid "Move or zoom the map to search somewhere else."
|
||||||
msgstr "Перемістіть або масштабуйте карту, щоб шукати в іншому місці."
|
msgstr "Перемістіть або масштабуйте карту, щоб шукати в іншому місці."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:471
|
#: lib/who_need_help_web/live/activity_live/index.ex:540
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:461
|
#: lib/who_need_help_web/live/request_live/index.ex:552
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Move the map, then search the newly visible area."
|
msgid "Move the map, then search the newly visible area."
|
||||||
msgstr "Перемістіть карту, а потім виконайте пошук у новій видимій області."
|
msgstr "Перемістіть карту, а потім виконайте пошук у новій видимій області."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:525
|
#: lib/who_need_help_web/live/request_live/index.ex:616
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open requests in this area"
|
msgid "No open requests in this area"
|
||||||
msgstr "У цій області немає відкритих заявок"
|
msgstr "У цій області немає відкритих заявок"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:517
|
#: lib/who_need_help_web/live/request_live/index.ex:608
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only requests from the selected map area will be loaded."
|
msgid "Only requests from the selected map area will be loaded."
|
||||||
msgstr "Буде завантажено лише заявки з вибраної області карти."
|
msgstr "Буде завантажено лише заявки з вибраної області карти."
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
#: lib/who_need_help_web/components/layouts/root.html.heex:8
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:613
|
#: lib/who_need_help_web/live/request_live/index.ex:704
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open request"
|
msgid "Open request"
|
||||||
msgstr "Відкрити заявку"
|
msgstr "Відкрити заявку"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:439
|
#: lib/who_need_help_web/live/activity_live/index.ex:503
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:431
|
#: lib/who_need_help_web/live/request_live/index.ex:517
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Optional text search"
|
msgid "Optional text search"
|
||||||
msgstr "Необов’язковий текстовий пошук"
|
msgstr "Необов’язковий текстовий пошук"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:592
|
#: lib/who_need_help_web/live/request_live/index.ex:683
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
msgid "Requests without map coordinates appear only when their public area description matches the text search."
|
||||||
msgstr "Заявки без координат на карті з’являються лише тоді, коли опис публічної області збігається з текстовим пошуком."
|
msgstr "Заявки без координат на карті з’являються лише тоді, коли опис публічної області збігається з текстовим пошуком."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:475
|
#: lib/who_need_help_web/live/activity_live/index.ex:544
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:465
|
#: lib/who_need_help_web/live/request_live/index.ex:556
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Results layout"
|
msgid "Results layout"
|
||||||
msgstr "Розташування результатів"
|
msgstr "Розташування результатів"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:621
|
#: lib/who_need_help_web/live/activity_live/index.ex:693
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:625
|
#: lib/who_need_help_web/live/request_live/index.ex:719
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search this area"
|
msgid "Search this area"
|
||||||
msgstr "Шукати в цій області"
|
msgstr "Шукати в цій області"
|
||||||
|
|
@ -4754,21 +4754,21 @@ msgstr "Шукати в цій області"
|
||||||
msgid "Static preview"
|
msgid "Static preview"
|
||||||
msgstr "Статичний перегляд"
|
msgstr "Статичний перегляд"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:494
|
#: lib/who_need_help_web/live/activity_live/index.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:484
|
#: lib/who_need_help_web/live/request_live/index.ex:575
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Together"
|
msgid "Together"
|
||||||
msgstr "Разом"
|
msgstr "Разом"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
#: lib/who_need_help_web/components/layouts/root.html.heex:6
|
||||||
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
#: lib/who_need_help_web/controllers/page_html/home.html.heex:160
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:609
|
#: lib/who_need_help_web/live/activity_live/index.ex:681
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
#: lib/who_need_help_web/live/activity_live/new.ex:355
|
||||||
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
#: lib/who_need_help_web/live/activity_live/new.ex:414
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
#: lib/who_need_help_web/live/activity_live/show.ex:546
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:602
|
#: lib/who_need_help_web/live/notification_live.ex:602
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:621
|
#: lib/who_need_help_web/live/notification_live.ex:621
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:612
|
#: lib/who_need_help_web/live/request_live/index.ex:703
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:485
|
#: lib/who_need_help_web/live/request_live/new.ex:485
|
||||||
#: lib/who_need_help_web/live/request_live/new.ex:563
|
#: lib/who_need_help_web/live/request_live/new.ex:563
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
#: lib/who_need_help_web/live/request_live/show.ex:1277
|
||||||
|
|
@ -5158,7 +5158,7 @@ msgid "Nearby alert deleted."
|
||||||
msgstr "Сповіщення поблизу видалено."
|
msgstr "Сповіщення поблизу видалено."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/notification_live.ex:456
|
#: lib/who_need_help_web/live/notification_live.ex:456
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:376
|
#: lib/who_need_help_web/live/request_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby requests"
|
msgid "Nearby requests"
|
||||||
msgstr "Заявки поблизу"
|
msgstr "Заявки поблизу"
|
||||||
|
|
@ -5498,7 +5498,7 @@ msgid "WebGL is unavailable in this browser, so the full map cannot start. Selec
|
||||||
msgstr "WebGL недоступний у цьому браузері, тому повна карта не може запуститися. Виберіть приклад нижче або спробуйте запустити карту ще раз."
|
msgstr "WebGL недоступний у цьому браузері, тому повна карта не може запуститися. Виберіть приклад нижче або спробуйте запустити карту ще раз."
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
#: lib/who_need_help_web/components/layouts/root.html.heex:7
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:610
|
#: lib/who_need_help_web/live/activity_live/index.ex:682
|
||||||
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
#: lib/who_need_help_web/live/activity_live/show.ex:547
|
||||||
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
#: lib/who_need_help_web/live/request_live/show.ex:1278
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -6063,7 +6063,7 @@ msgstr "Тепер ваш відгук видно"
|
||||||
msgid "Delivery settings"
|
msgid "Delivery settings"
|
||||||
msgstr "Налаштування доставки"
|
msgstr "Налаштування доставки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:569
|
#: lib/who_need_help_web/live/request_live/index.ex:660
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Expires"
|
msgid "Expires"
|
||||||
msgstr "Спливає"
|
msgstr "Спливає"
|
||||||
|
|
@ -6083,12 +6083,12 @@ msgstr "Сповіщення поруч"
|
||||||
msgid "Notification sections"
|
msgid "Notification sections"
|
||||||
msgstr "Розділи сповіщень"
|
msgstr "Розділи сповіщень"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:605
|
#: lib/who_need_help_web/live/activity_live/index.ex:674
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activities"
|
msgid "%{count} activities"
|
||||||
msgstr "Активностей: %{count}"
|
msgstr "Активностей: %{count}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} activity in this map area"
|
msgid "%{count} activity in this map area"
|
||||||
msgid_plural "%{count} activities in this map area"
|
msgid_plural "%{count} activities in this map area"
|
||||||
|
|
@ -6096,17 +6096,17 @@ msgstr[0] "%{count} активність у цій області карти"
|
||||||
msgstr[1] "%{count} активності в цій області карти"
|
msgstr[1] "%{count} активності в цій області карти"
|
||||||
msgstr[2] "%{count} активностей у цій області карти"
|
msgstr[2] "%{count} активностей у цій області карти"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:614
|
#: lib/who_need_help_web/live/request_live/index.ex:705
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "%{count} requests"
|
msgid "%{count} requests"
|
||||||
msgstr "Запитів: %{count}"
|
msgstr "Запитів: %{count}"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:645
|
#: lib/who_need_help_web/live/activity_live/index.ex:717
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
msgid "Activities you create or ask to join will appear here. Leaving removes an activity from this list."
|
||||||
msgstr "Створені вами активності й ті, до яких ви попросили приєднатися, з’являться тут. Після виходу активність зникне зі списку."
|
msgstr "Створені вами активності й ті, до яких ви попросили приєднатися, з’являться тут. Після виходу активність зникне зі списку."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:393
|
#: lib/who_need_help_web/live/activity_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Activity views"
|
msgid "Activity views"
|
||||||
msgstr "Розділи активностей"
|
msgstr "Розділи активностей"
|
||||||
|
|
@ -6121,12 +6121,12 @@ msgstr "Оберіть категорію та зрозуміло опишіть
|
||||||
msgid "Confirm the safety guidance before asking nearby people for help."
|
msgid "Confirm the safety guidance before asking nearby people for help."
|
||||||
msgstr "Підтвердьте правила безпеки перед публікацією запиту."
|
msgstr "Підтвердьте правила безпеки перед публікацією запиту."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:659
|
#: lib/who_need_help_web/live/request_live/index.ex:753
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create request"
|
msgid "Create request"
|
||||||
msgstr "Створити запит"
|
msgstr "Створити запит"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:673
|
#: lib/who_need_help_web/live/request_live/index.ex:776
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Create your first request"
|
msgid "Create your first request"
|
||||||
msgstr "Створити перший запит"
|
msgstr "Створити перший запит"
|
||||||
|
|
@ -6141,43 +6141,43 @@ msgstr "Що потрібно зробити"
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Місце"
|
msgstr "Місце"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:399
|
#: lib/who_need_help_web/live/activity_live/index.ex:463
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My activities"
|
msgid "My activities"
|
||||||
msgstr "Мої активності"
|
msgstr "Мої активності"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:377
|
#: lib/who_need_help_web/live/request_live/index.ex:463
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:653
|
#: lib/who_need_help_web/live/request_live/index.ex:747
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "My requests"
|
msgid "My requests"
|
||||||
msgstr "Мої запити"
|
msgstr "Мої запити"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:398
|
#: lib/who_need_help_web/live/activity_live/index.ex:462
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Nearby activities"
|
msgid "Nearby activities"
|
||||||
msgstr "Активності поруч"
|
msgstr "Активності поруч"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:643
|
#: lib/who_need_help_web/live/activity_live/index.ex:715
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No activities yet"
|
msgid "No activities yet"
|
||||||
msgstr "Активностей поки немає"
|
msgstr "Активностей поки немає"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No open activities in this area"
|
msgid "No open activities in this area"
|
||||||
msgstr "У цій області немає відкритих активностей"
|
msgstr "У цій області немає відкритих активностей"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:668
|
#: lib/who_need_help_web/live/request_live/index.ex:771
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No requests yet"
|
msgid "No requests yet"
|
||||||
msgstr "Запитів поки немає"
|
msgstr "Запитів поки немає"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:527
|
#: lib/who_need_help_web/live/activity_live/index.ex:596
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only activities from the selected map area will be loaded."
|
msgid "Only activities from the selected map area will be loaded."
|
||||||
msgstr "Буде завантажено лише активності з вибраної області карти."
|
msgstr "Буде завантажено лише активності з вибраної області карти."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:604
|
#: lib/who_need_help_web/live/activity_live/index.ex:673
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open activity"
|
msgid "Open activity"
|
||||||
msgstr "Відкрити активність"
|
msgstr "Відкрити активність"
|
||||||
|
|
@ -6187,12 +6187,12 @@ msgstr "Відкрити активність"
|
||||||
msgid "Request form steps"
|
msgid "Request form steps"
|
||||||
msgstr "Кроки створення запиту"
|
msgstr "Кроки створення запиту"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:371
|
#: lib/who_need_help_web/live/request_live/index.ex:457
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Request views"
|
msgid "Request views"
|
||||||
msgstr "Розділи запитів"
|
msgstr "Розділи запитів"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:670
|
#: lib/who_need_help_web/live/request_live/index.ex:773
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Requests you publish or accept will appear here."
|
msgid "Requests you publish or accept will appear here."
|
||||||
msgstr "Тут з’являться запити, які ви створили або прийняли."
|
msgstr "Тут з’являться запити, які ви створили або прийняли."
|
||||||
|
|
@ -6217,7 +6217,7 @@ msgstr "Укажіть терміновість і час закриття за
|
||||||
msgid "Share only as much location detail as helpers need."
|
msgid "Share only as much location detail as helpers need."
|
||||||
msgstr "Покажіть помічникам лише необхідну інформацію про місце."
|
msgstr "Покажіть помічникам лише необхідну інформацію про місце."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:607
|
#: lib/who_need_help_web/live/activity_live/index.ex:679
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The map is unavailable in this browser. Activity details remain usable."
|
msgid "The map is unavailable in this browser. Activity details remain usable."
|
||||||
msgstr "Карта недоступна в цьому браузері. Інформація про активності залишається доступною."
|
msgstr "Карта недоступна в цьому браузері. Інформація про активності залишається доступною."
|
||||||
|
|
@ -6227,7 +6227,7 @@ msgstr "Карта недоступна в цьому браузері. Інфо
|
||||||
msgid "Timing"
|
msgid "Timing"
|
||||||
msgstr "Час"
|
msgstr "Час"
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:655
|
#: lib/who_need_help_web/live/request_live/index.ex:749
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Track requests you created and requests you accepted as a helper."
|
msgid "Track requests you created and requests you accepted as a helper."
|
||||||
msgstr "Стежте за створеними запитами й тими, які ви прийняли як помічник."
|
msgstr "Стежте за створеними запитами й тими, які ви прийняли як помічник."
|
||||||
|
|
@ -6888,11 +6888,32 @@ msgstr "Що мають бачити люди до схвалення?"
|
||||||
msgid "Choose the meeting point on the map or use your current location."
|
msgid "Choose the meeting point on the map or use your current location."
|
||||||
msgstr "Оберіть місце зустрічі на карті або скористайтеся своїм поточним місцезнаходженням."
|
msgstr "Оберіть місце зустрічі на карті або скористайтеся своїм поточним місцезнаходженням."
|
||||||
|
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:458
|
#: lib/who_need_help_web/live/activity_live/index.ex:522
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:517
|
#: lib/who_need_help_web/live/activity_live/index.ex:586
|
||||||
#: lib/who_need_help_web/live/activity_live/index.ex:635
|
#: lib/who_need_help_web/live/activity_live/index.ex:707
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:448
|
#: lib/who_need_help_web/live/request_live/index.ex:534
|
||||||
#: lib/who_need_help_web/live/request_live/index.ex:507
|
#: lib/who_need_help_web/live/request_live/index.ex:598
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:763
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loading results…"
|
msgid "Loading results…"
|
||||||
msgstr "Завантажуємо результати…"
|
msgstr "Завантажуємо результати…"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:676
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching activities are listed beside the map."
|
||||||
|
msgstr "Досягнуто максимального масштабу. Відповідні заходи перелічено поруч із картою."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:707
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Maximum zoom reached. Matching requests are listed beside the map."
|
||||||
|
msgstr "Досягнуто максимального масштабу. Відповідні заявки перелічено поруч із картою."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/activity_live/index.ex:535
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching activities with map locations"
|
||||||
|
msgstr "із %{count} відповідних заходів із місцезнаходженням на карті"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/live/request_live/index.ex:547
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "of %{count} matching requests with map locations"
|
||||||
|
msgstr "із %{count} відповідних заявок із місцезнаходженням на карті"
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,11 @@ defmodule WhoNeedHelp.ActivitiesTest do
|
||||||
|
|
||||||
cluster = Enum.find(items, &match?(%{type: "cluster", count: 3}, &1))
|
cluster = Enum.find(items, &match?(%{type: "cluster", count: 3}, &1))
|
||||||
assert cluster
|
assert cluster
|
||||||
|
assert cluster.point_count == 3
|
||||||
|
assert cluster.hierarchy_level == 11
|
||||||
|
assert String.starts_with?(cluster.cluster_id, "activity:11:")
|
||||||
|
assert String.starts_with?(cluster.parent_cluster_id, "activity:10:")
|
||||||
|
assert cluster.expansion_zoom > 9
|
||||||
assert_in_delta cluster.latitude, 50.45, 0.000_001
|
assert_in_delta cluster.latitude, 50.45, 0.000_001
|
||||||
assert_in_delta cluster.longitude, 30.52, 0.000_001
|
assert_in_delta cluster.longitude, 30.52, 0.000_001
|
||||||
assert_in_delta cluster.bounds.west, 30.52, 0.000_001
|
assert_in_delta cluster.bounds.west, 30.52, 0.000_001
|
||||||
|
|
@ -456,9 +461,33 @@ defmodule WhoNeedHelp.ActivitiesTest do
|
||||||
assert_in_delta cluster.bounds.north, 50.45, 0.000_001
|
assert_in_delta cluster.bounds.north, 50.45, 0.000_001
|
||||||
|
|
||||||
assert Enum.any?(items, fn
|
assert Enum.any?(items, fn
|
||||||
%{type: "activity", id: id} -> id == sparse.id
|
%{
|
||||||
_item -> false
|
type: "activity",
|
||||||
|
id: id,
|
||||||
|
hierarchy_level: 11,
|
||||||
|
parent_cluster_id: "activity:10:" <> _
|
||||||
|
} ->
|
||||||
|
id == sparse.id
|
||||||
|
|
||||||
|
_item ->
|
||||||
|
false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
world_items =
|
||||||
|
Activities.map_discovery_items(
|
||||||
|
context.outsider_scope,
|
||||||
|
%{},
|
||||||
|
viewport!(-179.999, -85.0, 179.999, 85.0, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
represented_count =
|
||||||
|
Enum.reduce(world_items, 0, fn
|
||||||
|
%{type: "cluster", count: count}, total -> total + count
|
||||||
|
_point, total -> total + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert represented_count ==
|
||||||
|
Activities.count_map_discovery_items(context.outsider_scope, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "scale fixture activities keep distinct synthetic public map coordinates", context do
|
test "scale fixture activities keep distinct synthetic public map coordinates", context do
|
||||||
|
|
|
||||||
43
test/who_need_help/help/discovery_cluster_test.exs
Normal file
43
test/who_need_help/help/discovery_cluster_test.exs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
defmodule WhoNeedHelp.Help.DiscoveryClusterTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
alias WhoNeedHelp.Help.DiscoveryCluster
|
||||||
|
|
||||||
|
test "map zooms select stable hierarchy levels" do
|
||||||
|
assert DiscoveryCluster.level_for_zoom(0) == 2
|
||||||
|
assert DiscoveryCluster.level_for_zoom(5.49) == 7
|
||||||
|
assert DiscoveryCluster.level_for_zoom(5.99) == 7
|
||||||
|
assert DiscoveryCluster.level_for_zoom(6) == 8
|
||||||
|
assert DiscoveryCluster.level_for_zoom(22) == 24
|
||||||
|
|
||||||
|
assert_in_delta(
|
||||||
|
DiscoveryCluster.cell_size_meters(8),
|
||||||
|
DiscoveryCluster.cell_size_meters(7) / 2,
|
||||||
|
0.000_001
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "cluster ids and parents form a deterministic quadtree" do
|
||||||
|
assert DiscoveryCluster.cluster_id(:request, 8, 123, 456) == "request:8:123:456"
|
||||||
|
assert DiscoveryCluster.parent_id(:request, 8, 123, 456) == "request:7:61:228"
|
||||||
|
assert DiscoveryCluster.parent_id(:activity, 0, 0, 0) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
test "expansion zoom is the first child level that separates member bounds" do
|
||||||
|
level = 7
|
||||||
|
cell = DiscoveryCluster.cell_size_meters(level)
|
||||||
|
west = -DiscoveryCluster.world_half_meters() + cell * 10 + cell * 0.1
|
||||||
|
south = -DiscoveryCluster.world_half_meters() + cell * 20 + cell * 0.1
|
||||||
|
|
||||||
|
assert DiscoveryCluster.expansion_zoom(
|
||||||
|
level,
|
||||||
|
west,
|
||||||
|
south,
|
||||||
|
west + cell * 0.6,
|
||||||
|
south + cell * 0.6
|
||||||
|
) == 6
|
||||||
|
|
||||||
|
assert DiscoveryCluster.expansion_zoom(level, west, south, west, south) == 22
|
||||||
|
assert DiscoveryCluster.expansion_zoom(24, west, south, west, south) == 22
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -109,47 +109,6 @@ defmodule WhoNeedHelp.Help.DiscoveryViewportTest do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "derives cluster detail from both geographic bounds and rendered pixels" do
|
|
||||||
{:ok, city} =
|
|
||||||
DiscoveryViewport.cast(%{
|
|
||||||
west: 30,
|
|
||||||
south: 50,
|
|
||||||
east: 31,
|
|
||||||
north: 51,
|
|
||||||
zoom: 9,
|
|
||||||
width: 800,
|
|
||||||
height: 600
|
|
||||||
})
|
|
||||||
|
|
||||||
{:ok, neighborhood} =
|
|
||||||
DiscoveryViewport.cast(%{
|
|
||||||
west: 30.4,
|
|
||||||
south: 50.4,
|
|
||||||
east: 30.6,
|
|
||||||
north: 50.6,
|
|
||||||
zoom: 13,
|
|
||||||
width: 800,
|
|
||||||
height: 600
|
|
||||||
})
|
|
||||||
|
|
||||||
{:ok, wide_canvas} =
|
|
||||||
DiscoveryViewport.cast(%{
|
|
||||||
west: 30,
|
|
||||||
south: 50,
|
|
||||||
east: 31,
|
|
||||||
north: 51,
|
|
||||||
zoom: 9,
|
|
||||||
width: 1600,
|
|
||||||
height: 1200
|
|
||||||
})
|
|
||||||
|
|
||||||
assert DiscoveryViewport.cluster_cell_meters(city) >
|
|
||||||
DiscoveryViewport.cluster_cell_meters(neighborhood)
|
|
||||||
|
|
||||||
assert DiscoveryViewport.cluster_cell_meters(city) >
|
|
||||||
DiscoveryViewport.cluster_cell_meters(wide_canvas)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "serializes stable URL parameters and compares visible areas" do
|
test "serializes stable URL parameters and compares visible areas" do
|
||||||
{:ok, viewport} =
|
{:ok, viewport} =
|
||||||
DiscoveryViewport.cast(%{
|
DiscoveryViewport.cast(%{
|
||||||
|
|
|
||||||
|
|
@ -564,6 +564,11 @@ defmodule WhoNeedHelp.MutualAidFlowTest do
|
||||||
|
|
||||||
cluster = Enum.find(items, &match?(%{type: "cluster", count: 3}, &1))
|
cluster = Enum.find(items, &match?(%{type: "cluster", count: 3}, &1))
|
||||||
assert cluster
|
assert cluster
|
||||||
|
assert cluster.point_count == 3
|
||||||
|
assert cluster.hierarchy_level == 11
|
||||||
|
assert String.starts_with?(cluster.cluster_id, "request:11:")
|
||||||
|
assert String.starts_with?(cluster.parent_cluster_id, "request:10:")
|
||||||
|
assert cluster.expansion_zoom > viewport.zoom
|
||||||
assert_in_delta cluster.latitude, 50.4501, 0.000_001
|
assert_in_delta cluster.latitude, 50.4501, 0.000_001
|
||||||
assert_in_delta cluster.longitude, 30.52345, 0.000_001
|
assert_in_delta cluster.longitude, 30.52345, 0.000_001
|
||||||
assert_in_delta cluster.bounds.west, 30.5234, 0.000_001
|
assert_in_delta cluster.bounds.west, 30.5234, 0.000_001
|
||||||
|
|
@ -572,8 +577,17 @@ defmodule WhoNeedHelp.MutualAidFlowTest do
|
||||||
assert_in_delta cluster.bounds.north, 50.4501, 0.000_001
|
assert_in_delta cluster.bounds.north, 50.4501, 0.000_001
|
||||||
|
|
||||||
assert Enum.any?(items, fn
|
assert Enum.any?(items, fn
|
||||||
%{type: "request", id: id, exact: true} -> id == sparse_request.id
|
%{
|
||||||
_item -> false
|
type: "request",
|
||||||
|
id: id,
|
||||||
|
exact: true,
|
||||||
|
hierarchy_level: 11,
|
||||||
|
parent_cluster_id: "request:10:" <> _
|
||||||
|
} ->
|
||||||
|
id == sparse_request.id
|
||||||
|
|
||||||
|
_item ->
|
||||||
|
false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
dense_ids = MapSet.new(dense_requests, & &1.id)
|
dense_ids = MapSet.new(dense_requests, & &1.id)
|
||||||
|
|
@ -582,6 +596,21 @@ defmodule WhoNeedHelp.MutualAidFlowTest do
|
||||||
%{type: "request", id: id} -> MapSet.member?(dense_ids, id)
|
%{type: "request", id: id} -> MapSet.member?(dense_ids, id)
|
||||||
_item -> false
|
_item -> false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
world_items =
|
||||||
|
Help.map_discovery_items(
|
||||||
|
context.helper_scope,
|
||||||
|
%{},
|
||||||
|
viewport!(-179.999, -85.0, 179.999, 85.0, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
represented_count =
|
||||||
|
Enum.reduce(world_items, 0, fn
|
||||||
|
%{type: "cluster", count: count}, total -> total + count
|
||||||
|
_point, total -> total + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert represented_count == Help.count_map_discovery_items(context.helper_scope, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "map discovery does not expose an exact-for-match coordinate", context do
|
test "map discovery does not expose an exact-for-match coordinate", context do
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user