Skip to content

Commit

Permalink
Merge branch 'dev' into batch-ui-otp2-fares
Browse files Browse the repository at this point in the history
  • Loading branch information
miles-grant-ibigroup authored Sep 13, 2023
2 parents 2c6aacd + 3f01238 commit b43473a
Show file tree
Hide file tree
Showing 32 changed files with 484 additions and 448 deletions.
1 change: 1 addition & 0 deletions example-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ persistence:
# otp_middleware:
# apiBaseUrl: https://otp-middleware.example.com
# apiKey: your-middleware-api-key
# supportsPushNotifications: true # If not set, push notification settings will not be shown.

### Adding additional menu items to the main menu items. Use the separator flag
### to include a separator line if you have groups of menu items
Expand Down
14 changes: 9 additions & 5 deletions i18n/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,14 @@ actions:
setPaymentError: "Error setting payment info:"
setRequestStatusError: "Error setting request status:"
location:
deniedAccessAlert: >
Access to your location is blocked.
To use your current location, enable location permissions from your
browser, and reload the page.
geolocationNotSupportedError: Geolocation not supported by your browser
unknownPositionError: Unknown error getting position
userDeniedPermission: User denied permission
map:
currentLocation: (Current Location)
user:
Expand Down Expand Up @@ -130,6 +136,7 @@ common:
walk: Walk
notifications:
email: email
push: push notifications
sms: SMS
places:
custom: custom
Expand Down Expand Up @@ -353,10 +360,8 @@ components:
description: The content you requested is not available.
header: Content not found
NotificationPrefsPane:
description: You can receive notifications about trips you frequently take.
noneSelect: Don't notify me
notificationChannelPrompt: How would you like to receive notifications?
notificationEmailDetail: "Notification emails will be sent to:"
noDeviceForPush: Register your device using the mobile app to access push notifications.
notificationChannelPrompt: "Receive notifications about your saved trips via:"
OTP2ErrorRenderer:
LOCATION_NOT_FOUND:
body: >-
Expand Down Expand Up @@ -408,7 +413,6 @@ components:
prompt: "Enter your phone number for SMS notifications:"
requestNewCode: Request a new code
sendVerificationText: Send verification text
smsDetail: "SMS notifications will be sent to:"
verificationCode: "Verification code:"
verificationInstructions: >
Please check the SMS messaging app on your mobile phone for a text message
Expand Down
5 changes: 3 additions & 2 deletions i18n/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ common:
walk: Caminar
notifications:
email: correo electrónico
push: notificaciones push
sms: Mensaje de texto
places:
custom: personalizado
Expand Down Expand Up @@ -359,8 +360,9 @@ components:
header: No se encontró el contenido
NotificationPrefsPane:
description: Puede recibir notificaciones sobre los viajes que realiza con frecuencia.
noDeviceForPush: Regístrese con la aplicación móvil para acceder a esta configuración.
noneSelect: No enviar notificaciones
notificationChannelPrompt: ¿Cómo desea recibir las notificaciones?
notificationChannelPrompt: "Recibir notificaciones para sus viajes guardados por:"
notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
Expand All @@ -375,7 +377,6 @@ components:
texto:
requestNewCode: Solicitar un nuevo código
sendVerificationText: Enviar texto de verificación
smsDetail: "Las notificaciones por mensaje de texto se enviarán a:"
verificationCode: "Código de verificación:"
verificationInstructions: >
Por favor, compruebe en la aplicación de mensajería de texto de su
Expand Down
18 changes: 10 additions & 8 deletions i18n/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,14 @@ actions:
setPaymentError: "Erreur sur les coordonnées de paiement :"
setRequestStatusError: "Erreur sur l'état de la requête :"
location:
deniedAccessAlert: >
L'accès à votre position est refusé.
Pour utiliser votre emplacement actuel, permettez-en l'accès depuis votre
navigateur, et ouvrez de nouveau cette page.
geolocationNotSupportedError: La géolocalisation n'est pas prise en charge par votre navigateur.
unknownPositionError: Erreur inconnue lors de la détection de votre emplacement.
userDeniedPermission: Refusé par l'utilisateur
map:
currentLocation: (Emplacement actuel)
user:
Expand Down Expand Up @@ -139,6 +145,7 @@ common:
walk: À pied
notifications:
email: e-mail
push: notifications push
sms: SMS
places:
custom: divers
Expand Down Expand Up @@ -178,7 +185,7 @@ components:
AdvancedOptions:
bannedRoutes: Choisissez les lignes à éviter…
bikeTolerance: Tolérance au vélo
preferredRoutes: Choisissez les lignes preferées
preferredRoutes: Choisissez les lignes préferées
walkTolerance: Tolérance à la marche
AfterSignInScreen:
mainTitle: Redirection...
Expand Down Expand Up @@ -366,12 +373,8 @@ components:
description: Le contenu que vous avez demandé n'est pas disponible.
header: Contenu introuvable
NotificationPrefsPane:
description: >-
Vous pouvez recevoir des notifications sur les trajets que vous effectuez
fréquemment.
noneSelect: Ne pas me notifier
notificationChannelPrompt: Comment voulez-vous recevoir vos notifications ?
notificationEmailDetail: "Les courriers de notification seront envoyés à :"
noDeviceForPush: Inscrivez-vous avec l'application mobile pour accéder à ce paramètre.
notificationChannelPrompt: "Recevoir des notifications sur vos trajets par :"
OTP2ErrorRenderer:
LOCATION_NOT_FOUND:
body: >-
Expand Down Expand Up @@ -425,7 +428,6 @@ components:
prompt: "Entrez votre numéro de téléphone pour les SMS de notification :"
requestNewCode: Envoyer un nouveau code
sendVerificationText: Envoyer le SMS de vérification
smsDetail: "Les SMS de notification seront envoyés au :"
verificationCode: "Code de vérification :"
verificationInstructions: >
Un SMS vous a été envoyé avec un code de vérification. Veuillez taper ce
Expand Down
5 changes: 5 additions & 0 deletions i18n/i18n-exceptions.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"groups": {
"common.notifications.*": [
"email",
"sms",
"push"
],
"components.OTP2ErrorRenderer.*.body": [
"LOCATION_NOT_FOUND",
"NO_STOPS_IN_RANGE",
Expand Down
7 changes: 2 additions & 5 deletions i18n/ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ common:
walk: 걷기
notifications:
email: 이메일
push: 푸시 알림
sms: SMS
places:
custom: 사용자 정의
Expand Down Expand Up @@ -324,10 +325,7 @@ components:
description: 요청한 콘텐츠를 사용할 수 없습니다.
header: 콘텐츠를 찾을 수 없음
NotificationPrefsPane:
description: 자주 가는 트립에 대한 알림을 받을 수 있습니다.
noneSelect: 알림 거부
notificationChannelPrompt: 알림을 어떻게 받고 싶습니까?
notificationEmailDetail: "알림 이메일이 다음으로 전송됩니다:"
notificationChannelPrompt: "저장된 여행의 알림을 받는 방법:"
PhoneNumberEditor:
changeNumber: 번호 변경
invalidCode: 확인 코드 6 자리를 입력하세요.
Expand All @@ -338,7 +336,6 @@ components:
prompt: "SMS 알림 수신을 위한 전화번호를 입력하세요:"
requestNewCode: 새 코드 요청
sendVerificationText: 확인 텍스트 전송
smsDetail: "SMS 알림이 다음으로 전송됩니다:"
verificationCode: "확인 코드:"
verificationInstructions: |
휴대폰의 SMS 메시지 앱에서 인증 코드를 확인하고 아래에 코드를 입력하세요(코드는 10분 후에 만료됩니다).
Expand Down
9 changes: 2 additions & 7 deletions i18n/vi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ common:
walk: Đi bộ
notifications:
email: e-mail
push: thông báo đẩy
sms: tin nhắn
places:
custom: phong tục
Expand Down Expand Up @@ -333,12 +334,7 @@ components:
description: Nội dung bạn yêu cầu không có sẵn.
header: Không tìm thấy nội dung
NotificationPrefsPane:
description: >-
Bạn có thể nhận được thông báo về các chuyến đi bạn thường xuyên thực
hiện.
noneSelect: Đừng thông báo cho tôi
notificationChannelPrompt: Bạn muốn nhận thông báo như thế nào?
notificationEmailDetail: "Email thông báo sẽ được gửi đến:"
notificationChannelPrompt: "Nhận thông báo về các chuyến đi đã lưu bằng:"
PhoneNumberEditor:
changeNumber: Thay đổi số điện thoại
invalidCode: Vui lòng nhập 6 chữ số cho mã xác thực.
Expand All @@ -349,7 +345,6 @@ components:
prompt: "Nhập số điện thoại của bạn để nhận thông báo SMS:"
requestNewCode: Yêu cầu một mã mới
sendVerificationText: Gửi văn bản xác minh
smsDetail: "Thông báo SMS sẽ được gửi đến:"
verificationCode: "Mã xác nhận:"
verificationInstructions: >
Vui lòng kiểm tra ứng dụng nhắn tin SMS trên điện thoại di động của bạn để
Expand Down
7 changes: 2 additions & 5 deletions i18n/zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ common:
walk: 步行
notifications:
email: 电子邮件
push: 推送通知
sms: 短信
places:
custom: 习俗
Expand Down Expand Up @@ -325,10 +326,7 @@ components:
description: 您要求的内容不存在.
header: 未找到内容
NotificationPrefsPane:
description: 你可以收到关于你常用行程的通知.
noneSelect: 不要通知我
notificationChannelPrompt: 您希望如何接收通知?
notificationEmailDetail: "通知邮件将被发送至:"
notificationChannelPrompt: "如何接收已保存行程的通知:"
PhoneNumberEditor:
changeNumber: 更改电话号码
invalidCode: 请输入6位数的验证码.
Expand All @@ -339,7 +337,6 @@ components:
prompt: "输入你的电话号码以便收到短信通知:"
requestNewCode: 申请一个新的代码
sendVerificationText: 发送验证短信
smsDetail: "短信通知将被发送到:"
verificationCode: "验证码:"
verificationInstructions: |
请检查您手机上的短信应用查看是否有验证码的短信并输入以下代码 (代码在10分钟后失效).
Expand Down
47 changes: 4 additions & 43 deletions lib/actions/apiV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { zoomToPlace } from './map'

const { generateCombinations, generateOtp2Query } = coreUtils.queryGen
const { getTripOptionsFromQuery, getUrlParams } = coreUtils.query
const { convertGraphQLResponseToLegacy } = coreUtils.itinerary
const { randId } = coreUtils.storage

const LIGHT_GRAY = '666666'
Expand Down Expand Up @@ -782,47 +783,6 @@ const pickupDropoffTypeToOtp1 = (otp2Type) => {
}
}

/**
* Converts a leg from GraphQL format to legacy REST format.
* @param leg OTP2 GraphQL style leg
* @returns REST shaped leg
*/
const processLeg = (leg) => ({
...leg,
agencyBrandingUrl: leg.agency?.url,
agencyName: leg.agency?.name,
agencyUrl: leg.agency?.url,
alerts: aggregateAlerts(
leg.agency?.alerts,
leg.route?.alerts,
leg.to?.stop?.alerts,
leg.from?.stop?.alerts
),
alightRule: pickupDropoffTypeToOtp1(leg.dropoffType),
boardRule: pickupDropoffTypeToOtp1(leg.pickupType),
dropOffBookingInfo: {
latestBookingTime: leg.dropOffBookingInfo
},
from: {
...leg.from,
stopCode: leg.from.stop?.code,
stopId: leg.from.stop?.gtfsId
},
route: leg.route?.shortName,
routeColor: leg.route?.color,
routeId: leg.route?.id,
routeLongName: leg.route?.longName,
routeShortName: leg.route?.shortName,
routeTextColor: leg.route?.textColor,
to: {
...leg.to,
stopCode: leg.to.stop?.code,
stopId: leg.to.stop?.gtfsId
},
tripHeadsign: leg.trip?.tripHeadsign,
tripId: leg.trip?.gtfsId
})

const queryParamConfig = { modeButtons: DelimitedArrayParam }

export function routingQuery(searchId = null, updateSearchInReducer) {
Expand Down Expand Up @@ -919,7 +879,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {

dispatch(setItineraryView(ItineraryView.LIST))

combinations.forEach((combo) => {
combinations.forEach((combo, index) => {
const query = generateOtp2Query(combo)
dispatch(
createGraphQLQueryAction(
Expand Down Expand Up @@ -962,7 +922,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
const withCollapsedShortNames =
response.data?.plan?.itineraries?.map((itin) => ({
...itin,
legs: itin.legs?.map(processLeg)
legs: itin.legs?.map(convertGraphQLResponseToLegacy)
}))

/* It is possible for a NO_TRANSIT_CONNECTION error to be
Expand All @@ -982,6 +942,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
}

return {
index,
response: {
plan: {
...response.data?.plan,
Expand Down
23 changes: 14 additions & 9 deletions lib/actions/field-trip.js
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ function checkValidityAndCapacity(state, request) {

// iterate through itineraries to check validity and assign field trip
// groups
response.plan.itineraries.forEach((itinerary) => {
response.plan.itineraries.forEach((itinerary, itinIdx) => {
let itineraryCapacity = Number.POSITIVE_INFINITY

// check each individual trip to see if there aren't any trips in this
Expand Down Expand Up @@ -744,12 +744,13 @@ function checkValidityAndCapacity(state, request) {
// A field trip response is guaranteed to have only one itinerary, so it
// ok to set the itinerary by response as an array with a single
// itinerary.
assignedItinerariesByResponse[responseIdx] = [
{
...itinerary,
fieldTripGroupSize: Math.min(itineraryCapacity, remainingGroupSize)
}
]
if (!assignedItinerariesByResponse[responseIdx]) {
assignedItinerariesByResponse[responseIdx] = {}
}
assignedItinerariesByResponse[responseIdx][itinIdx] = {
...itinerary,
fieldTripGroupSize: Math.min(itineraryCapacity, remainingGroupSize)
}
remainingGroupSize -= itineraryCapacity
}
})
Expand Down Expand Up @@ -844,8 +845,12 @@ function makeFieldTripPlanRequests(request, outbound, intl) {
// I do not believe that it is worth the effort. I am instead in favor of
// re-building field trip from the ground up as a separate application.
setInterval(() => {
const activeItineraries = getActiveItineraries(getState())
if (activeItineraries.length >= numRequests) {
const searchResponse = getState().otp.searches[searchId]?.response
const activeItineraries =
searchResponse?.reduce((prev, resp) => {
return (prev += resp?.plan?.itineraries?.length || 0)
}, 0) || 0
if (activeItineraries >= numRequests) {
resolve()
}
}, 20)
Expand Down
27 changes: 24 additions & 3 deletions lib/actions/location.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { createAction } from 'redux-actions'
import { Dispatch } from 'redux'
import { IntlShape } from 'react-intl'
import { isMobile } from '@opentripplanner/core-utils/lib/ui'

import { setLocationToCurrent } from './map'

Expand Down Expand Up @@ -47,9 +48,29 @@ export function getCurrentPosition(
// On error
(error) => {
console.log('error getting current position', error)
// FIXME, analyze error code to produce better error message.
// See https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError
dispatch(receivedPositionError({ error }))
// On desktop, after user clicks "Use location" from the location fields,
// show an alert and explain if location is blocked.
// TODO: Consider moving the handling of unavailable location to the location-field component.
if (!isMobile() && error.code === 1) {
window.alert(
intl.formatMessage({
id: 'actions.location.deniedAccessAlert'
})
)
}
const newError = { ...error }
if (error.code === 1) {
// i18n for user-denied location message (error.code = 1 on secure origins).
if (
window.location.protocol === 'https:' ||
window.location.host.startsWith('localhost:')
) {
newError.message = intl.formatMessage({
id: 'actions.location.userDeniedPermission'
})
}
}
dispatch(receivedPositionError({ error: newError }))
},
// Options
{ enableHighAccuracy: true }
Expand Down
Loading

0 comments on commit b43473a

Please sign in to comment.