diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index a3a1b7bc5..65c9368a3 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -46,7 +46,7 @@ exports[`components > viewers > nearby view renders nothing on a blank page 1`] className="nearby-view base-color-bg" >
viewers > nearby view renders nothing on a blank page 1`] } >
    viewers > nearby view renders proper scooter dates 1`] = ` className="nearby-view base-color-bg" >
    viewers > nearby view renders proper scooter dates 1`] = ` } >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = `
        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = `

              viewers > nearby view renders proper scooter dates 1`] = `
                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
              • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                  viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                    viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` >
                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = `
                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="988" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` >
                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = `
                                  viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                • viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                      viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="984" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` >
                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = `
                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                        • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = `

                                            viewers > nearby view renders proper scooter dates 1`] = `
                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                            • viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                    viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                      viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` >
                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = `
                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                          • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > {leadTimeInMinutes} мин до запланированного времени отправления + notifications: за {leadTimeInMinutes} мин до запланированного времени + отправления notificationsDisabled: "Уведомления: отключены" TripTools: copyLink: Скопировать ссылку @@ -693,17 +702,23 @@ components: storeTripHistory: Сохранять историю поездок updating: Обновляется UserSettings: - confirmDeletion: "Недавние поисковые запросы и\_(или) места сохранены. Отключение сохранения недавних мест и\_(или) поисковых запросов приведет к удалению этих элементов. Продолжить?" + confirmDeletion: "Недавние поисковые запросы и (или) места сохранены. Отключение + сохранения недавних мест и (или) поисковых запросов приведет к удалению этих + элементов. Продолжить?" favoriteStops: Избранные остановки myPreferences: Мои параметры mySavedPlaces: Мои сохраненные места (изменить) noFavoriteStops: Избранные остановки recentPlaces: Недавние места - recentSearchSummary: "Режим «{mode}». {from}\_— {to}" + recentSearchSummary: "Режим «{mode}». {from} — {to}" recentSearches: Недавние поисковые запросы - rememberSearches: "Сохранить недавние места\_/ поисковые запросы?" + rememberSearches: "Сохранить недавние места / поисковые запросы?" stopId: "Идентификатор остановки: {stopId}" - storageDisclaimer: "Все сохраненные параметры, места и настройки будут храниться в локальном хранилище браузера. TriMet не получит доступ к данным о вашем доме, месте работы или другим местоположениям. В любой момент вы можете отключить сохранение недавних мест\_/ поисковых запросов и очистить список местоположений дома/работы, а также избранных остановок.\n" + storageDisclaimer: "Все сохраненные параметры, места и настройки будут храниться + в локальном хранилище браузера. TriMet не получит доступ к данным о вашем доме, + месте работы или другим местоположениям. В любой момент вы можете отключить + сохранение недавних мест / поисковых запросов и очистить список местоположений + дома/работы, а также избранных остановок.\n" UserTripSettings: forgetOptions: Удалить варианты rememberOptions: Сохранить варианты поездки @@ -725,12 +740,12 @@ components: prompt: Куда вы хотите отправиться? config: accessModes: - bicycle: "Общественный транспорт\_+\_личный велосипед" - bicycle_rent: "Общественный транспорт\_+\_прокат велосипеда" + bicycle: "Общественный транспорт + личный велосипед" + bicycle_rent: "Общественный транспорт + прокат велосипеда" car_hail: Заказная поездка car_park: Парковочное место - micromobility: "Общественный транспорт\_+\_личный самокат" - micromobility_rent: "Общественный транспорт\_+\_прокат электросамоката" + micromobility: "Общественный транспорт + личный самокат" + micromobility_rent: "Общественный транспорт + прокат электросамоката" bicycleModes: bicycle: Личный велосипед bicycle_rent: Прокат велосипедов diff --git a/i18n/tl.yml b/i18n/tl.yml index 4d48060ef..ad174d969 100644 --- a/i18n/tl.yml +++ b/i18n/tl.yml @@ -45,7 +45,8 @@ actions: confirmDeletePlace: Gusto mo bang alisin ang lugar na ito? emailVerificationResent: Ipinadala ulit ang mensahe ng pag-verify sa email. genericError: "Nagka-error: {err}" - itineraryExistenceCheckFailed: Nagka-error sa pagtingin kung posible ang napili mong biyahe. + itineraryExistenceCheckFailed: Nagka-error sa pagtingin kung posible ang napili + mong biyahe. mustAcceptTermsToSavePlace: >- Pakitanggap ang Mga Tuntunin ng Paggamit (sa ilalim ng Aking Account) para mag-save ng mga lokasyon. @@ -106,13 +107,11 @@ common: submitting: Isinusumite… "yes": Oo itineraryDescriptions: - calories: "{calories, number} Cal" fareUnknown: Walang impormasyon sa pamasahe noItineraryToDisplay: Walang ipapakitang itinerary. relativeCo2: > {co2} {isMore, select, true {mas maraming} other {mas kaunting} } CO₂ kaysa magmaneho nang mag-isa - transfers: "{transfers, plural, =0 {} one {# transfer} other {# transfers}}" linkOpensNewWindow: (Magbubukas sa bagong window) modes: bicycle_rent: Bikeshare @@ -151,7 +150,6 @@ common: enterStartLocation: Ilagay ang lokasyon ng pagsisimula o {mapAction} sa mapa… tap: tap time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: a few seconds nDays: "{days, plural, =1 {one day} other {# days}}" @@ -204,7 +202,8 @@ components: ang pampublikong transportasyon sa pagpili mo ng mode. origin: pinagmulan planTripTooltip: Planuhin ang biyahe - validationMessage: "Ilarawan ang mga sumusunod na field para makapagplano ng biyahe: {issues}" + validationMessage: "Ilarawan ang mga sumusunod na field para makapagplano ng biyahe: + {issues}" BeforeSignInScreen: mainTitle: Sina-sign in ka message: > @@ -263,7 +262,6 @@ components: ariaLabel: Pag-navigate sa form ItinerarySummary: itineraryDetails: Mga detalye ng itinerary - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: Ilagay ang lokasyon setDestination: Itakda ang Patutunguhan @@ -396,7 +394,8 @@ components: invalidCode: Maglagay ng 6 na digit para sa code sa pag-validate. invalidPhone: Maglagay ng valid na numero ng telepono. phoneNumberSubmitted: Matagumpay na naisumite ang numero ng teleponong {phoneNumber}. - phoneNumberVerified: Matagumpay na na-verify ang numero ng teleponong {phoneNumber} . + phoneNumberVerified: Matagumpay na na-verify ang numero ng teleponong {phoneNumber} + . placeholder: Ilagay ang numero ng iyong telepono prompt: "Ilagay ang numero ng iyong telepono para sa mga SMS na notification:" requestNewCode: Humiling ng bagong code @@ -585,9 +584,11 @@ components: travelingAt: Bumibiyahe nang {milesPerHour} vehicleName: Sasakyan {vehicleNumber} TripBasicsPane: - checkingItineraryExistence: Tinitingnan kung may itinerary para sa bawat araw ng linggo... + checkingItineraryExistence: Tinitingnan kung may itinerary para sa bawat araw + ng linggo... tripDaysPrompt: Anong mga araw mo ginagawa ang biyaheng ito? - tripIsAvailableOnDaysIndicated: Available ang iyong biyahe sa mga araw ng linggo na nakasaad sa itaas. + tripIsAvailableOnDaysIndicated: Available ang iyong biyahe sa mga araw ng linggo + na nakasaad sa itaas. tripNamePrompt: "Pangalanan ang biyaheng ito:" tripNotAvailableOnDay: Hindi available ang biyahe sa {repeatedDay} unsavedChangesExistingTrip: >- @@ -632,7 +633,8 @@ components: unknownState: Hindi Alam ang Status ng Biyahe untogglePause: Ipagpatuloy inactive: - description: Ipagpatuloy ang pagsubaybay sa biyahe para makita ang updated na status + description: Ipagpatuloy ang pagsubaybay sa biyahe para makita ang updated na + status heading: Naka-pause ang pagsubaybay sa biyahe nextTripNotPossible: description: > @@ -651,7 +653,8 @@ components: description: Hinihintay na makalkula ang biyahe. heading: Hindi pa nakakalkula ang biyahe snoozed: - description: I-unsnooze ang pagsubaybay sa biyahe para makita ang updated na status. + description: I-unsnooze ang pagsubaybay sa biyahe para makita ang updated na + status. heading: Naka-snooze ang pagsubaybay sa biyahe ngayong araw upcoming: nextTripBegins: >- @@ -661,7 +664,8 @@ components: Magsisimula ang biyahe nang {tripStart, time, short}. (Magsisimula ang realtime na pagsubaybay nang {monitoringStart, time, short}.) tripStartIsDelayed: Naantala ang oras ng pagsisimula ng biyahe nang {duration}! - tripStartIsEarly: Nagsisimula na ang biyahe {duration} na mas maaga kaysa sa inaasahan! + tripStartIsEarly: Nagsisimula na ang biyahe {duration} na mas maaga kaysa sa + inaasahan! tripStartsSoonNoUpdates: >- Malapit nang magsimula ang biyahe (walang realtime na update na available). diff --git a/i18n/vi.yml b/i18n/vi.yml index 316b37876..b10292003 100644 --- a/i18n/vi.yml +++ b/i18n/vi.yml @@ -5,7 +5,8 @@ actions: callQuerySaveError: "Lỗi khi lưu trữ các truy vấn cuộc gọi: {err}" callSaveError: "Không thể lưu cuộc gọi: {err}" checkSessionError: "Lỗi khi thiết lập phiên ủy quyền: {err}" - couldNotFindCallError: Không thể tìm thấy cuộc gọi. Đang hủy yêu cầu lưu truy vấn. + couldNotFindCallError: Không thể tìm thấy cuộc gọi. Đang hủy yêu cầu lưu truy + vấn. fetchCallsError: "Lỗi khi tìm nạp cuộc gọi: {err}" queryFetchError: "Lỗi khi tìm nạp các truy vấn: {err}" fieldTrip: @@ -28,7 +29,8 @@ actions: Không thể lưu kế hoạch chuyến đi: Không thể lưu kế hoạch chuyến đi này do thiếu sức chứa trên một hoặc nhiều xe. Vui lòng lên kế hoạch lại chuyến đi của bạn. - maxTripRequestsExceeded: Đã vượt quá số lượng yêu cầu chuyến đi mà không có kết quả hợp lệ + maxTripRequestsExceeded: Đã vượt quá số lượng yêu cầu chuyến đi mà không có kết + quả hợp lệ saveItinerariesError: "Không lưu được hành trình: {err}" setDateError: "Lỗi khi cài đặt ngày:" setGroupSizeError: "Lỗi khi cài đặt kích thước nhóm:" @@ -40,7 +42,8 @@ actions: Để sử dụng địa điểm hiện tại của mình, quý vị hãy cho phép sử dụng vị trí trong trình duyệt và tải lại trang này. - geolocationNotSupportedError: Định vị địa lý không được hỗ trợ bởi trình duyệt của bạn + geolocationNotSupportedError: Định vị địa lý không được hỗ trợ bởi trình duyệt + của bạn unknownPositionError: Lỗi không xác định khi tìm vị trí userDeniedPermission: Người dùng từ chối cấp quyền map: @@ -52,7 +55,8 @@ actions: confirmDeletePlace: Bạn có muốn loại bỏ nơi này không? emailVerificationResent: Thông báo xác minh email đã được gửi lại. genericError: "Phát sinh lỗi: {err}" - itineraryExistenceCheckFailed: Lỗi kiểm tra xem chuyến đi được chọn của bạn là có thể. + itineraryExistenceCheckFailed: Lỗi kiểm tra xem chuyến đi được chọn của bạn là + có thể. mustAcceptTermsToSavePlace: >- Vui lòng chấp nhận Điều Khoản Sử Dụng (trong phần Tài Khoản Của Tôi) để lưu lại địa điểm. @@ -112,12 +116,10 @@ common: submitting: Đang gửi… "yes": Đúng itineraryDescriptions: - calories: "{calories, number} calo" fareUnknown: Không có thông tin giá vé noItineraryToDisplay: Không có hành trình để hiển thị. relativeCo2: | {co2} CO₂ {isMore, select, true {nhiều} other {ít} } hơn so với xe hơi - transfers: "{transfers, plural, =0 {} other {# chuyển}}" linkOpensNewWindow: (Mở khoảng thời gian mới) modes: bicycle_rent: Chia sẻ xe đạp @@ -156,7 +158,6 @@ common: enterStartLocation: Nhập vị trí bắt đầu hoặc {mapAction} vào bản đồ… tap: chạm time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: vài giây nDays: "{days} ngày" @@ -168,12 +169,14 @@ common: {} other {# giây}} components: A11yPrefs: - accessibilityRoutingByDefault: Thích những chuyến đi có thể truy cập theo mặc định + accessibilityRoutingByDefault: Thích những chuyến đi có thể truy cập theo mặc + định AccountSetupFinishPane: message: Bạn đã sẵn sàng để bắt đầu lên kế hoạch cho các chuyến đi của bạn. AddPlaceButton: addPlace: Thêm địa điểm - needOriginDestination: Xác định nguồn gốc hoặc đích đến để thêm các địa điểm trung gian + needOriginDestination: Xác định nguồn gốc hoặc đích đến để thêm các địa điểm trung + gian tooManyPlaces: Địa điểm trung gian tối đa đạt được AdvancedOptions: bannedRoutes: Chọn các tuyến đường bị cấm… @@ -259,14 +262,14 @@ components: editPlaceGeneric: Chỉnh sửa vị trí invalidAddress: Vui lòng cài đặt một vị trí cho nơi này. invalidName: Vui lòng nhập tên cho nơi này. - nameAlreadyUsed: Bạn đã sử dụng tên này cho một nơi khác. Vui lòng nhập một tên khác. + nameAlreadyUsed: Bạn đã sử dụng tên này cho một nơi khác. Vui lòng nhập một tên + khác. placeNotFound: Không tìm thấy địa điểm placeNotFoundDescription: Xin lỗi, địa điểm được yêu cầu không được tìm thấy. FormNavigationButtons: ariaLabel: Điều hướng hình thức ItinerarySummary: itineraryDetails: Chi tiết hành trình - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: Nhập vị trí setDestination: Chọn điểm đến @@ -335,8 +338,10 @@ 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: - devicesRegistered: "{count, plural, one {# device} other {# devices}} đã đăng ký" - noDeviceForPush: Đăng ký thiết bị của quý vị bằng ứng dụng di động để nhận thông báo đẩy. + devicesRegistered: "{count, plural, one {# device} other {# devices}} đã đăng + ký" + noDeviceForPush: Đăng ký thiết bị của quý vị bằng ứng dụng di động để nhận thông + báo đẩy. notificationChannelPrompt: "Nhận thông báo về các chuyến đi đã lưu bằng:" OTP2ErrorRenderer: LOCATION_NOT_FOUND: @@ -579,16 +584,21 @@ components: travelingAt: di chuyển với tốc độ {milesPerHour} vehicleName: Phương tiện giao thông {vehicleNumber} TripBasicsPane: - checkingItineraryExistence: Kiểm tra sự tồn tại của hành trình cho mỗi ngày trong tuần… + checkingItineraryExistence: Kiểm tra sự tồn tại của hành trình cho mỗi ngày trong + tuần… tripDaysPrompt: Bạn thực hiện chuyến đi này vào những ngày nào? - tripIsAvailableOnDaysIndicated: Chuyến đi của bạn có sẵn vào những ngày trong tuần như đã nêu ở trên. + tripIsAvailableOnDaysIndicated: Chuyến đi của bạn có sẵn vào những ngày trong + tuần như đã nêu ở trên. tripNamePrompt: "Vui lòng cung cấp tên cho chuyến đi này:" tripNotAvailableOnDay: Chuyến đi không có sẵn vào {repeatedDay} - unsavedChangesExistingTrip: Bạn chưa lưu chuyến đi của mình. Nếu bạn rời đi, những thay đổi sẽ bị mất. - unsavedChangesNewTrip: Bạn chưa lưu chuyến đi mới của mình. Nếu bạn rời đi, nó sẽ bị mất. + unsavedChangesExistingTrip: Bạn chưa lưu chuyến đi của mình. Nếu bạn rời đi, những + thay đổi sẽ bị mất. + unsavedChangesNewTrip: Bạn chưa lưu chuyến đi mới của mình. Nếu bạn rời đi, nó + sẽ bị mất. TripNotificationsPane: advancedSettings: Cài đặt nâng cao - altRouteRecommended: Một tuyến đường hoặc điểm trung chuyển thay thế được khuyến nghị + altRouteRecommended: Một tuyến đường hoặc điểm trung chuyển thay thế được khuyến + nghị delaysAboveThreshold: Có sự chậm trễ hoặc gián đoạn của hơn howToReceiveAlerts: > Để nhận thông báo cho các chuyến đi đã lưu của bạn, bật thông báo trong @@ -597,7 +607,8 @@ components: notificationsTurnedOff: Thông báo được tắt cho tài khoản của bạn. notifyViaChannelWhen: "Thông báo cho tôi qua {channel} khi:" oneHour: 1 tiếng - realtimeAlertFlagged: Có một cảnh báo thời gian thực được gắn cờ trên hành trình của tôi + realtimeAlertFlagged: Có một cảnh báo thời gian thực được gắn cờ trên hành trình + của tôi timeBefore: "{time} trước" TripStatus: alerts: "{alerts, plural, one {# cảnh báo!} other {# cảnh báo!}}" @@ -610,7 +621,8 @@ components: earlyHeading: >- Chuyến đi đang diễn ra và sẽ đến sớm hơn {formattedDuration} so với dự kiến! - noDataHeading: Chuyến đi đang được tiến hành (không có cập nhật thời gian thực có sẵn). + noDataHeading: Chuyến đi đang được tiến hành (không có cập nhật thời gian thực + có sẵn). onTimeHeading: Chuyến đi đang được tiến hành và đúng giờ. base: lastCheckedDefaultText: Thời gian được kiểm tra lần cuối không xác định @@ -653,7 +665,8 @@ components: tripStartIsEarly: >- Thời gian bắt đầu chuyến đi đang diễn ra sớm hơn {duration} so với dự kiến! - tripStartsSoonNoUpdates: Chuyến đi đang bắt đầu sớm (không có cập nhật về thời gian thực). + tripStartsSoonNoUpdates: Chuyến đi đang bắt đầu sớm (không có cập nhật về thời + gian thực). tripStartsSoonOnTime: Chuyến đi đang bắt đầu sớm và sắp đúng giờ. TripSummary: arriveAt: "Đến nơi " diff --git a/i18n/zh_Hans.yml b/i18n/zh_Hans.yml index 5d4b6a419..c3012c95a 100644 --- a/i18n/zh_Hans.yml +++ b/i18n/zh_Hans.yml @@ -99,12 +99,10 @@ common: submitting: 正在提交… "yes": 是 itineraryDescriptions: - calories: "{calories, number} 大卡" fareUnknown: 无票价信息 noItineraryToDisplay: 没有显示行程. relativeCo2: | {co2} {isMore, select, true {更多} other {更少} } CO₂ 比单独驾车 - transfers: "{transfers, plural, =0 {} other {# 换乘}}" linkOpensNewWindow: (打开新窗口) modes: bicycle_rent: 共享单车 @@ -143,7 +141,6 @@ common: enterStartLocation: 输入出发地点或{mapAction}地图… tap: 点击 time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: 几秒钟 nDays: "{days} 天" @@ -244,7 +241,6 @@ components: ariaLabel: 表格导航 ItinerarySummary: itineraryDetails: 行程详情 - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: 输入位置 setDestination: 设置目的地 diff --git a/i18n/zh_Hant.yml b/i18n/zh_Hant.yml index 4fbc7d8fd..b18d02dc0 100644 --- a/i18n/zh_Hant.yml +++ b/i18n/zh_Hant.yml @@ -99,12 +99,10 @@ common: submitting: 正在提交… "yes": 是 itineraryDescriptions: - calories: "{calories, number}卡" fareUnknown: 無票價資訊 noItineraryToDisplay: 沒有預定行程可顯示。 relativeCo2: | {co2}比單獨開車排放的CO₂{isMore, select, true {要多} other {少}} - transfers: "{transfers}次轉乘" linkOpensNewWindow: (開啟新視窗) modes: bicycle_rent: 自行車共享 @@ -143,7 +141,6 @@ common: enterStartLocation: 輸入開始位置或{mapAction} 地圖…… tap: 輕觸 time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: 幾秒鐘 nDays: "{days}天" @@ -244,7 +241,6 @@ components: ariaLabel: 表單導航 ItinerarySummary: itineraryDetails: 路線詳細資訊 - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: 輸入位置 setDestination: 設定目的地 diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index e7deb84e3..15d3f5d77 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -505,6 +505,10 @@ export const fetchNearby = (position, radius, currentServiceWeek) => { export const findStopTimesForStop = (params) => function (dispatch, getState) { + // If the stop is already in the store, don't fetch it again, unless we are forcing a refetch + if (!params.forceFetch && getState().otp.transitIndex.stops[params.stopId]) + return + dispatch(fetchingStopTimesForStop(params)) const { date, stopId } = params const timeZone = getState().otp.config.homeTimezone @@ -1023,7 +1027,9 @@ export function routingQuery(searchId = null, updateSearchInReducer) { numItineraries: numItineraries || getDefaultNumItineraries(config) } if (config.mobilityProfile) { - baseQuery.mobilityProfile = loggedInUser?.mobilityProfile?.mobilityMode + baseQuery.mobilityProfile = + currentQuery.mobilityProfile || + loggedInUser?.mobilityProfile?.mobilityMode } // Generate combinations if the modes for query are not specified in the query // FIXME: BICYCLE_RENT does not appear in this list unless TRANSIT is also enabled. diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js index 0b667dbf1..dafa74ebc 100644 --- a/lib/actions/field-trip.js +++ b/lib/actions/field-trip.js @@ -33,6 +33,7 @@ import { setPendingRequests, updateOtpUrlParams } from './api' +import { setLocation } from './map' import { toggleCallHistory } from './call-taker' if (typeof fetch === 'undefined') require('isomorphic-fetch') @@ -534,8 +535,8 @@ function prepareQueryParams(request, outbound) { const hasExistingLocations = currentQuery.from || currentQuery.to const locations = !hasExistingLocations || - window.confirm( - 'Use custom set locations? Pressing "Cancel" will use the locations you have typed in. Pressing "OK" will use the locations currently saved to the field trip' + !window.confirm( + 'Use custom set locations? Pressing "OK" will use the locations you have typed in. Pressing "Cancel" will use the locations currently saved to the field trip' ) ? await planParamsToQueryAsync(locationsToGeocode, config) : { from: currentQuery.from, to: currentQuery.to } @@ -1078,6 +1079,8 @@ export function clearActiveFieldTrip() { return function (dispatch) { dispatch(setActiveFieldTrip(null)) dispatch(clearActiveSearch()) + dispatch(setLocation({ location: null, locationType: 'from' })) + dispatch(setLocation({ location: null, locationType: 'to' })) dispatch(setQueryParam({ numItineraries: undefined })) dispatch(clearSaveable()) } diff --git a/lib/actions/ui.js b/lib/actions/ui.js index cdd0691da..a548a43bc 100644 --- a/lib/actions/ui.js +++ b/lib/actions/ui.js @@ -47,6 +47,9 @@ const viewRoute = createAction('SET_VIEWED_ROUTE') export const toggleAutoRefresh = createAction('TOGGLE_AUTO_REFRESH') const settingItineraryView = createAction('SET_ITINERARY_VIEW') export const setPopupContent = createAction('SET_POPUP_CONTENT') +export const setNetworkConnectionLost = createAction( + 'SET_NETWORK_CONNECTION_LOST' +) // This code-less action calls the reducer code // and thus resets the session timeout. diff --git a/lib/actions/user.js b/lib/actions/user.js index 837d7341e..a65f93665 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -41,6 +41,7 @@ const setCurrentUserMonitoredTrips = createAction( const setCurrentUserTripRequests = createAction( 'SET_CURRENT_USER_TRIP_REQUESTS' ) +const setDependentUserInfo = createAction('SET_DEPENDENT_USER_INFO') const setLastPhoneSmsRequest = createAction('SET_LAST_PHONE_SMS_REQUEST') export const setPathBeforeSignIn = createAction('SET_PATH_BEFORE_SIGNIN') export const clearItineraryExistence = createAction('CLEAR_ITINERARY_EXISTENCE') @@ -693,6 +694,29 @@ export function checkItineraryExistence(trip, intl) { } } +export function getDependentUserInfo(userIds, intl) { + return async function (dispatch, getState) { + const state = getState() + const { accessToken, apiBaseUrl, apiKey } = getMiddlewareVariables(state) + const requestUrl = `${apiBaseUrl}${API_OTPUSER_PATH}/getdependentmobilityprofile?dependentuserids=${userIds}` + + const { data, status } = await secureFetch( + requestUrl, + accessToken, + apiKey, + 'GET' + ) + + if (status === 'success' && data) { + dispatch(setDependentUserInfo(data)) + } else { + alert( + intl.formatMessage({ id: 'actions.user.getDependentUserInfoFailed' }) + ) + } + } +} + /** * Plans a new trip for the current date given the query parameters in the given * monitored trip diff --git a/lib/components/admin/field-trip-list.js b/lib/components/admin/field-trip-list.js index f74dbe841..29728d403 100644 --- a/lib/components/admin/field-trip-list.js +++ b/lib/components/admin/field-trip-list.js @@ -129,7 +129,7 @@ class FieldTripList extends Component { } _onCloseActiveFieldTrip = () => { - this.props.setActiveFieldTrip(null) + this.props.clearActiveFieldTrip() } _getReportUrl = () => { @@ -268,6 +268,7 @@ const mapStateToProps = (state) => { } const mapDispatchToProps = { + clearActiveFieldTrip: fieldTripActions.clearActiveFieldTrip, fetchFieldTripDetails: fieldTripActions.fetchFieldTripDetails, fetchFieldTrips: fieldTripActions.fetchFieldTrips, setActiveFieldTrip: fieldTripActions.setActiveFieldTrip, diff --git a/lib/components/app/app.css b/lib/components/app/app.css index c35529d15..697857947 100644 --- a/lib/components/app/app.css +++ b/lib/components/app/app.css @@ -338,6 +338,9 @@ height: 100%; width: 100%; } +.otp .navbar { + z-index: 25; +} /** These changes kick in when the map is hidden. These rules ensure that the entire "sidebar" (which at this point fills the entire screen) scrolls as a single unit. diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 6ca1f6da2..30001e1b3 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -25,6 +25,7 @@ import ViewerContainer from '../viewers/viewer-container' interface Props { activeSearch: any currentQuery: any + geocoderResultsOrder?: Array intl: IntlShape mainPanelContent: number mobile?: boolean @@ -89,7 +90,13 @@ class BatchRoutingPanel extends Component { } render() { - const { activeSearch, intl, mobile, showUserSettings } = this.props + const { + activeSearch, + geocoderResultsOrder, + intl, + mobile, + showUserSettings + } = this.props const { planTripClicked } = this.state const mapAction = mobile ? intl.formatMessage({ @@ -157,6 +164,7 @@ class BatchRoutingPanel extends Component {

                                                                  { showClearButton={!mobile} /> { const { mainPanelContent } = state.otp.ui const currentQuery = state.otp.currentQuery + const geocoderResultsOrder = state.otp.config?.geocoder?.geocoderResultsOrder return { activeSearch: getActiveSearch(state), currentQuery, + geocoderResultsOrder, mainPanelContent, showUserSettings } diff --git a/lib/components/app/desktop-nav.tsx b/lib/components/app/desktop-nav.tsx index b2e1ad3c2..8ce6df8d9 100644 --- a/lib/components/app/desktop-nav.tsx +++ b/lib/components/app/desktop-nav.tsx @@ -13,6 +13,7 @@ import { DEFAULT_APP_TITLE } from '../../util/constants' import InvisibleA11yLabel from '../util/invisible-a11y-label' import NavLoginButtonAuth0 from '../user/nav-login-button-auth0' +import { NetworkConnectionBanner } from './network-connection-banner' import AppMenu, { Icon } from './app-menu' import LocaleSelector from './locale-selector' import NavbarItem from './nav-item' @@ -59,6 +60,7 @@ const NavItemOnLargeScreens = styled(NavbarItem)` // Typscript TODO: otpConfig type export type Props = { locale: string + networkConnectionLost: boolean otpConfig: AppConfig popupTarget?: string setPopupContent: (url: string) => void @@ -79,6 +81,7 @@ export type Props = { */ const DesktopNav = ({ locale, + networkConnectionLost, otpConfig, popupTarget, setPopupContent @@ -158,6 +161,7 @@ const DesktopNav = ({ + ) } @@ -165,8 +169,10 @@ const DesktopNav = ({ // connect to the redux store const mapStateToProps = (state: AppReduxState) => { const { config: otpConfig } = state.otp + const { networkConnectionLost } = state.otp.ui.errors return { locale: state.otp.ui.locale, + networkConnectionLost, otpConfig, popupTarget: otpConfig.popups?.launchers?.toolbar } diff --git a/lib/components/app/network-connection-banner.tsx b/lib/components/app/network-connection-banner.tsx new file mode 100644 index 000000000..a323520ac --- /dev/null +++ b/lib/components/app/network-connection-banner.tsx @@ -0,0 +1,83 @@ +import { CSSTransition, TransitionGroup } from 'react-transition-group' +import { FormattedMessage } from 'react-intl' +import React, { useRef } from 'react' +import styled from 'styled-components' + +import { RED_ON_WHITE } from '../util/colors' +import InvisibleA11yLabel from '../util/invisible-a11y-label' + +const containerClassname = 'network-connection-banner' +const timeout = 250 + +const TransitionStyles = styled.div` + .${containerClassname} { + background: ${RED_ON_WHITE}; + border-left: 1px solid #e7e7e7; + border-right: 1px solid #e7e7e7; + color: #fff; + font-weight: 600; + padding: 5px; + position: absolute; + text-align: center; + top: 50px; + width: 100%; + // When banner is fully loaded, set z-index higher than nav so we're not seeing the nav border. + z-index: 26; + + @media (max-width: 768px) { + border: 0; + } + } + .${containerClassname}-enter { + opacity: 0; + transform: translateY(-100%); + } + .${containerClassname}-enter-active { + opacity: 1; + transform: translateY(0); + transition: opacity ${timeout}ms ease-in; + } + .${containerClassname}-exit { + opacity: 1; + transform: translateY(0); + z-index: 20; + } + .${containerClassname}-exit-active { + opacity: 0; + transform: translateY(-100%); + transition: opacity ${timeout}ms ease-in, transform ${timeout}ms ease-in; + z-index: 20; + } +` + +export const NetworkConnectionBanner = ({ + networkConnectionLost +}: { + networkConnectionLost: boolean +}): JSX.Element => { + const connectionLostBannerRef = useRef(null) + return ( + + + {networkConnectionLost ? ( + + ) : ( + + )} + + + {networkConnectionLost && ( + +
                                                                  + +
                                                                  +
                                                                  + )} +
                                                                  +
                                                                  + ) +} diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js index 2b2a44dfc..ee4c3c684 100644 --- a/lib/components/app/responsive-webapp.js +++ b/lib/components/app/responsive-webapp.js @@ -154,10 +154,13 @@ class ResponsiveWebapp extends Component { map, matchContentToUrl, parseUrlQueryString, - receivedPositionResponse + receivedPositionResponse, + setNetworkConnectionLost } = this.props // Add on back button press behavior. window.addEventListener('popstate', handleBackButtonPress) + window.addEventListener('online', () => setNetworkConnectionLost(false)) + window.addEventListener('offline', () => setNetworkConnectionLost(true)) // If a URL is detected without hash routing (e.g., http://localhost:9966?sessionId=test), // window.location.search will have a value. In this case, we need to redirect to the URL root with the @@ -180,10 +183,7 @@ class ResponsiveWebapp extends Component { navigator.geolocation.watchPosition( // On success (position) => { - // This object cloning is required to be allowed to read the position info twice - // on webkit browsers. - // See https://github.com/opentripplanner/otp-react-redux/pull/697 for details - receivedPositionResponse({ position: { ...position } }) + receivedPositionResponse({ position }) }, // On error (error) => { @@ -441,6 +441,7 @@ const mapStateToWrapperProps = (state) => { const mapWrapperDispatchToProps = { processSignIn: authActions.processSignIn, setLocale: uiActions.setLocale, + setNetworkConnectionLost: uiActions.setNetworkConnectionLost, showAccessTokenError: authActions.showAccessTokenError, showLoginError: authActions.showLoginError } diff --git a/lib/components/form/add-place-button.tsx b/lib/components/form/add-place-button.tsx index 5cecd5d11..ce585331b 100644 --- a/lib/components/form/add-place-button.tsx +++ b/lib/components/form/add-place-button.tsx @@ -22,7 +22,7 @@ const AddPlaceButton = ({ const disabled = !from || !to || maxPlacesDefined return (