Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions app/backend/src/couchers/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"cant_unsub_topic": "Sorry, you can't unsubscribe from that topic right now.",
"cant_write_reference_for_request": "You can't write a reference for that host request, or it wasn't found.",
"cant_write_reference_indicated_didnt_meetup": "You can't write a reference for that host request because you indicated that you didn't meet up.",
"chat_initiation_rate_limit": "You have messaged a lot of users in the past {{hours}} hours. To avoid spam, you can't contact any more users for now.",
"chat_initiation_rate_limit2_one": "You have messaged a lot of users in the past {{count}} hour. To avoid spam, you can't contact any more users for now.",
"chat_initiation_rate_limit2_other": "You have messaged a lot of users in the past {{count}} hours. To avoid spam, you can't contact any more users for now.",
"chat_not_found": "Couldn't find that chat.",
"city_required": "City is required.",
"community_not_found": "Community not found.",
Expand Down Expand Up @@ -76,7 +77,8 @@
"event_transfer_permission_denied": "You're not allowed to transfer that event.",
"events_not_enabled": "Events are not enabled in this group or community.",
"friend_request_not_found": "Couldn't find that friend request.",
"friend_request_rate_limit": "You have sent a lot of friend requests in the past {{hours}} hours. To avoid spam, you can't send any more for now.",
"friend_request_rate_limit2_one": "You have sent a lot of friend requests in the past {{count}} hour. To avoid spam, you can't send any more for now.",
"friend_request_rate_limit2_other": "You have sent a lot of friend requests in the past {{count}} hours. To avoid spam, you can't send any more for now.",
"friends_already_or_pending": "You are already friends with or have sent a friend request to that user.",
"after_item_not_found": "The item to place after was not found.",
"gallery_at_max_capacity": "The gallery is at maximum capacity and cannot accept more photos.",
Expand All @@ -86,9 +88,11 @@
"group_or_community_not_found": "Group or community not found.",
"host_request_in_past": "This host request is in the past.",
"host_request_not_found": "Couldn't find that host request.",
"host_request_rate_limit": "You have sent a lot of host requests in the past {{hours}} hours. To avoid spam, you can't send any more for now.",
"host_request_rate_limit2_one": "You have sent a lot of host requests in the past {{count}} hour. To avoid spam, you can't send any more for now.",
"host_request_rate_limit2_other": "You have sent a lot of host requests in the past {{count}} hours. To avoid spam, you can't send any more for now.",
"host_request_sent_or_received": "Can't only list sent and also only received requests.",
"host_request_too_short": "Host request cannot be shorter than {{chars}} characters.",
"host_request_too_short2_one": "Host request cannot be shorter than {{count}} character.",
"host_request_too_short2_other": "Host request cannot be shorter than {{count}} characters.",
"hosting_status_required": "Hosting status is required.",
"incomplete_profile_create_event": "You have to complete your profile before you can create an event.",
"incomplete_profile_send_message": "You have to complete your profile before you can send a message.",
Expand Down
4 changes: 2 additions & 2 deletions app/backend/src/couchers/servicers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,8 @@ def SendFriendRequest(
):
context.abort_with_error_code(
grpc.StatusCode.RESOURCE_EXHAUSTED,
"friend_request_rate_limit",
substitutions={"hours": str(RATE_LIMIT_HOURS)},
"friend_request_rate_limit2",
substitutions={"count": RATE_LIMIT_HOURS},
)

# TODO: Race condition where we can create two friend reqs, needs db constraint! See comment in table
Expand Down
4 changes: 2 additions & 2 deletions app/backend/src/couchers/servicers/conversations.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,8 @@ def CreateGroupChat(
):
context.abort_with_error_code(
grpc.StatusCode.RESOURCE_EXHAUSTED,
"chat_initiation_rate_limit",
substitutions={"hours": str(RATE_LIMIT_HOURS)},
"chat_initiation_rate_limit2",
substitutions={"count": RATE_LIMIT_HOURS},
)

group_chat = _create_chat(
Expand Down
8 changes: 4 additions & 4 deletions app/backend/src/couchers/servicers/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ def CreateHostRequest(
if not _is_host_request_long_enough(request.text):
context.abort_with_error_code(
grpc.StatusCode.INVALID_ARGUMENT,
"host_request_too_short",
substitutions={"chars": str(HOST_REQUEST_MIN_LENGTH_UTF16)},
"host_request_too_short2",
substitutions={"count": HOST_REQUEST_MIN_LENGTH_UTF16},
)

# Check if user has been sending host requests excessively
Expand All @@ -241,8 +241,8 @@ def CreateHostRequest(
):
context.abort_with_error_code(
grpc.StatusCode.RESOURCE_EXHAUSTED,
"host_request_rate_limit",
substitutions={"hours": str(RATE_LIMIT_HOURS)},
"host_request_rate_limit2",
substitutions={"count": RATE_LIMIT_HOURS},
)

conversation = Conversation()
Expand Down
6 changes: 3 additions & 3 deletions app/web/components/EditLocationMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ interface RadiusSliderProps {
commit(updates: Partial<ApproximateLocation>, shouldUpdate?: boolean): void;
initialRadius: number;
redrawMap(): void;
t: (key: string, options?: { radius?: number }) => string;
t: (key: string, options?: { count?: number }) => string;
}

function RadiusSlider({
Expand All @@ -384,8 +384,8 @@ function RadiusSlider({
</Typography>
<Slider
aria-labelledby="location-radius"
aria-valuetext={t("components.edit_location_map.radius_text", {
radius,
aria-valuetext={t("components.edit_location_map.radius_text2", {
count: radius,
})}
value={radius}
step={5}
Expand Down
9 changes: 4 additions & 5 deletions app/web/features/auth/signup/SignupFormContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ export default function SignupFormContent({
<Trans
i18nKey={
isNativeEmbed
? "landing:signup_description_no_link"
: "landing:signup_description"
? "landing:signup_description_no_link2"
: "landing:signup_description2"
}
values={{
user_count: signupInfo?.userCount
? Number(signupInfo.userCount).toLocaleString()
: "65k+",
// Number(...) returns NaN on bad input, and || treats it as false
count: Number(signupInfo?.userCount) || 65000,
}}
components={
isNativeEmbed
Expand Down
9 changes: 4 additions & 5 deletions app/web/features/landing/SocialProof.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,9 @@ const SocialProof = () => {
</Box>
) : (
<Typography sx={{ fontSize: "1.5rem", fontWeight: 500 }}>
{t("landing:num_users", {
numUsers: signupInfo?.userCount
? Number(signupInfo.userCount).toLocaleString()
: "56k+",
{t("landing:num_users2", {
// Number(...) returns NaN on bad input, and || treats it as false
count: Number(signupInfo?.userCount) || 56000,
})}
</Typography>
)}
Expand All @@ -132,7 +131,7 @@ const SocialProof = () => {
}}
/>
<Typography sx={{ fontSize: "1.5rem", fontWeight: 500 }}>
{t("landing:num_countries", { numCountries: 180 })}
{t("landing:num_countries2", { count: 180 })}
</Typography>
</Box>
<Box display="flex" alignItems={isMobile ? "flex-start" : "center"}>
Expand Down
12 changes: 8 additions & 4 deletions app/web/features/landing/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"introduction_subtitle": "Share your world, discover theirs. Authentic couch surfing experiences, built on trust and genuine connection—not transactions.",
"introduction_subtitle2": "Free forever. Community-led. Non-profit.",
"signup_header": "Join the Couchers.org community",
"signup_description": "Travel, host, and connect with {{ user_count }} members. <2>Learn more about us</2>.",
"signup_description_no_link": "Travel, host, and connect with {{ user_count }} members.",
"signup_description2_one": "Travel, host, and connect with {{count}} member. <2>Learn more about us</2>.",
"signup_description2_other": "Travel, host, and connect with {{count}} members. <2>Learn more about us</2>.",
"signup_description_no_link2_one": "Travel, host, and connect with {{count}} member.",
"signup_description_no_link2_other": "Travel, host, and connect with {{count}} members.",
"create_an_account": "Create an account",
"signup_continue": "Finish signing up",
"what_couchsurfing_title": "Couchers.org: a different way to travel",
Expand Down Expand Up @@ -38,7 +40,9 @@
"non_transactional_why": "It is fundamentally incompatible with having genuine interactions. It is healthy to only give or only receive and we should learn to be more comfortable with it.",
"why": "Why?",
"map_section_title": "Explore our global community",
"num_users": "{{numUsers}} members",
"num_countries": "{{numCountries}}+ countries",
"num_users2_one": "{{count}} member",
"num_users2_other": "{{count}} members",
"num_countries2_one": "{{count}}+ countries",
"num_countries2_other": "{{count}}+ countries",
"last_signup": "Last signup {{timeAgo}}"
}
3 changes: 2 additions & 1 deletion app/web/resources/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@
"location_publicly_visible": "This will be publicly visible",
"location_warn": "Click and drag the circle below to show people the approximate location of your home. Make sure your home is not at the center of the circle, so people will not know the exact location.",
"map_is_blank": "Missing coordinates, start by searching for a location with the map above",
"radius_text": "{{radius}} meters",
"radius_text2_one": "{{count}} meter",
"radius_text2_other": "{{count}} meters",
"no_location_results_text": "No results. Try searching for just the city.",
"no_map_support": "Your device doesn't support the map. Please make sure WebGL2 is enabled or try a different device/browser. Sorry for the trouble!",
"press_enter_to_search": "Press enter to search"
Expand Down
2 changes: 1 addition & 1 deletion docs/localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Placeholders allow inserting values known at runtime into the string. They are a
- ✅ **DO** use descriptive placeholder names that allow translators to anticipate the format of the substituted string. It's okay to be verbose!
- **Good** 👍: `{{full_name}}`, `{{date_and_time_with_day}}`, `{{amount_and_currency}}`.
- **Bad** 👎: `{{when}}`, `{{value}}`, `{{x}}`.
- ✅ **DO** allow for pluralization of integer values. i18next requires the placeholder to be named `{{count}}` and Weblate requires `en.json` to define both `***_one` and `***_other` string variants.
- ✅ **DO** allow for pluralization of integer values, even if they will never be 1. i18next requires the placeholder to be named `{{count}}` and Weblate requires `en.json` to define both `***_one` and `***_other` string variants.
- **Good** 👍: `member_count_one` = `{{count}} member` and `member_count_other` = `{{count}} members`.
- **Bad** 👎: `member_count` = `{{members}} members`, `member_count_plural` = `{{count}} members`.
- ✅ **DO** change the string key if the format or name of a placeholder changes, to force retranslation. If necessary, add a version suffix like "mystring2".
Expand Down
Loading