refactor: move 315 UI strings into the resource catalogue, and prove the escapes survive
Phase 4, second step, of docs/material-design-conformance.md. 251 distinct strings, 315
call sites, from literals inside composables to `stringResource(Res.string.…)`. Literals
in composables go 332 -> 76; `stringResource` goes 0 -> 374.
**The extractor took four attempts, and each failure is why it is checked in.**
*A bare `text = "…"` is not a Compose string.* `text` is an ordinary parameter name and
this tree uses it on data classes: `NavigationUIState.Loading(text = "…")` is not a
composable, and rewriting it failed with "@Composable invocations can only happen from the
context of a @Composable function". So `Text(`/`BasicText(` calls are brace-matched and
only literals genuinely inside one are touched.
*A regex over quote pairs is not a Kotlin lexer.* Matching `"[^"]*"` over a whole file
pairs one string's closing quote with the next string's opening quote, so "literals" came
out as several lines of Kotlin. Restricting the body to one line fixed that and left a
subtler version: `"a ${if (n == 1) "chunk" else "chunks"} b"` has two inner literals
belonging to an outer template, and left-to-right matching lifts them out as strings of
their own. The script decided `"chunk"` and `"note"` were UI text worth translating. It now
scans properly -- on an opening quote, walk forward tracking `${` depth, recursing over
nested literals, and stop at the closing quote at depth zero.
*A fragment is not a string.* `"a " + x + " b"` is one sentence in three pieces, and " b"
is not something a translator can work with -- word order differs between languages. Three
filters, because the fragments hide in three shapes: adjacent to a `+`, leading or trailing
whitespace or no letters at all (", " and ":"), and -- the one that needed a fourth pass --
a pluralisation where the *parenthesis* is adjacent to the `+` and neither literal is:
(if (proposal.eventCount == 2) "event" else "events") +
Testing the line rather than the literal catches those four sites while leaving a genuine
either/or alone: `if (session == null) "Start key ceremony" else "Try again"` has no `+`
and both branches are whole strings.
**Compose Resources is not aapt, and that was a bug this commit nearly shipped.** The
first version escaped apostrophes as `\'` and doubled `%`, which is what android's resource
compiler requires. Compose Resources does neither. `getString(Res.string.don_t_sign)`
returned
Don\'t sign
backslash included, and there are 30-odd apostrophes in this catalogue. Every one of them
would have rendered with a visible backslash, on screens nobody opens often.
What makes this worth a permanent test rather than a fixed script: escape handling is
**partial**, not absent. The same run showed `\n` *is* processed --
"Currently no messages have been shared.\nBreak the ice." comes back with a real newline.
So there is no family rule to rely on, and the next escape somebody adds needs checking on
its own.
`StringCatalogueJvmTest` asserts all three cases through `getString`, which is the
non-composable reader for the same resources and needs no composition. It found the bug
before a device did.
**Names are derived from content**, snake_cased and truncated at a word boundary:
`something_went_wrong`, `add_artifact_to_the_group_library`. The conventional shape for an
automated extraction, with a known cost -- rewording the copy leaves the name slightly
stale. The alternative, naming by *purpose*, needs somebody to read 315 call sites, and a
name asserting the wrong purpose is worse than one that is a little dated.
**1101 dead strings out, 251 live ones in.** The catalogue previously held the phoenix
wallet fork's entire string table with nothing referencing it; it now holds this app's own,
plus `app_name`.
**What is left, and why.** 76 literals: 46 interpolated, which need format placeholders and
an argument order decided per site, and 30 concatenation fragments, which need their
sentences reassembled first. Both are the next commit, and both are jobs where a script
should not guess.
**Tests.** 947 pass, 598 jvm over 73 classes and 349 android over 44, up from 944/595/349 --
three new assertions in one new class. `:composeApp:compileDebugKotlinAndroid` builds, the
debug apk installs and runs on emulator-5554 with its text reading correctly through
onboarding and the message list. `m3-audit.sh --check` exits 0.
`ChronicleApplyJvmTest` failed once during this commit's verification and passed on rerun;
it is the pre-existing 1-in-8 flake filed during phase 3, and nothing here touches
chronicle code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,4 +21,255 @@
|
||||
"XML file ... is not valid. Check the file content."
|
||||
-->
|
||||
<string name="app_name">Mantra</string>
|
||||
<string name="add_a_dialect_the_group_can_translate_into">Add a dialect the group can translate into</string>
|
||||
<string name="add_artifact_to_library">Add artifact to library</string>
|
||||
<string name="add_artifact_to_the_group_library">Add artifact to the group library</string>
|
||||
<string name="add_chapter">Add chapter</string>
|
||||
<string name="add_dialect">Add dialect</string>
|
||||
<string name="add_to_group">Add to group</string>
|
||||
<string name="add_translation">Add translation</string>
|
||||
<string name="after_this_there_is_no_turning_back">After this there is no turning back.</string>
|
||||
<string name="all_broadcasts_are_queued_so_that_we_can">All broadcasts are queued so that we can manage data usage on metered connections.</string>
|
||||
<string name="any_amount">Any amount</string>
|
||||
<string name="article">ARTICLE</string>
|
||||
<string name="artifact_detail">Artifact detail</string>
|
||||
<string name="as_long_as_you_control_your_keys_there_can">As long as you control your keys there can be no dispute about who YOU actually is.</string>
|
||||
<string name="back">Back</string>
|
||||
<string name="be_sure_to_keep_this_nsec_safe">Be sure to keep this nsec safe.</string>
|
||||
<string name="be_the_first_to_comment">Be the first to comment.</string>
|
||||
<string name="bio">Bio</string>
|
||||
<string name="block_user">Block user</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="change_account">Change account</string>
|
||||
<string name="chapter_detail">Chapter detail</string>
|
||||
<string name="chapter_name">Chapter name</string>
|
||||
<string name="chapter_translation">Chapter translation</string>
|
||||
<string name="chapters">Chapters</string>
|
||||
<string name="choose_who_to_chat_with">Choose who to chat with</string>
|
||||
<string name="close">Close</string>
|
||||
<string name="copy_url">Copy URL</string>
|
||||
<string name="country">Country</string>
|
||||
<string name="create_chat">Create chat</string>
|
||||
<string name="create_new_chat">Create new chat</string>
|
||||
<string name="create_profile">Create profile</string>
|
||||
<string name="create_project">Create project</string>
|
||||
<string name="create_the_admins_group">Create the #admins group</string>
|
||||
<string name="creating_new_chat">Creating new chat.</string>
|
||||
<string name="currently_no_contacts_please_search_and_chat">Currently no contacts. Please search and chat with a few people.</string>
|
||||
<string name="currently_no_messages_have_been_shared">Currently no messages have been shared.\nBreak the ice.</string>
|
||||
<string name="delete_group">Delete group</string>
|
||||
<string name="details">Details</string>
|
||||
<string name="dialect_name">Dialect name</string>
|
||||
<string name="dialects">Dialects</string>
|
||||
<string name="direct_message_detail">Direct message detail</string>
|
||||
<string name="direct_message_functionality_will_be_here">Direct message functionality will be here.</string>
|
||||
<string name="direct_message_via_npub">Direct message via npub</string>
|
||||
<string name="don_t_sign">Don't sign</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="edit_profile">Edit profile</string>
|
||||
<string name="eg_chapter_1_the_beginning">eg. Chapter 1 — The Beginning</string>
|
||||
<string name="eg_first_edition">eg. First Edition</string>
|
||||
<string name="eg_https_harper_com_2_kill_bird">eg. https://harper.com/2-kill-Bird</string>
|
||||
<string name="eg_lesotho">eg. Lesotho</string>
|
||||
<string name="eg_sesotho">eg. Sesotho</string>
|
||||
<string name="eg_st">eg. st</string>
|
||||
<string name="eg_to_kill_a_mocking_bird">eg. To Kill a Mocking Bird</string>
|
||||
<string name="end_this">end this</string>
|
||||
<string name="ended">ENDED</string>
|
||||
<string name="enter_the_name_you_want_to_use_for_your">Enter the name you want to use for your group</string>
|
||||
<string name="enter_the_name_you_want_to_use_for_your_2">Enter the name you want to use for your profile</string>
|
||||
<string name="enter_the_nsec_or_npub_read_only_that_you">Enter the nsec or npub (read only) that you want to sign in as</string>
|
||||
<string name="enter_the_translation_for_this_chunk">Enter the translation for this chunk</string>
|
||||
<string name="events_are_indexed_so_that_we_can_deliver_a">Events are indexed so that we can deliver a premium local first experience.</string>
|
||||
<string name="everything_else">Everything else</string>
|
||||
<string name="everything_is_cryptographical_sound_just">Everything is cryptographical sound. Just announcing your profile to the world.</string>
|
||||
<string name="everything_is_cryptographical_sound_just_2">Everything is cryptographical sound. Just indexing your profile on the device.</string>
|
||||
<string name="everything_is_cryptographical_sound_just_3">Everything is cryptographical sound. Just need to queue your profile and announce it to the world.</string>
|
||||
<string name="expired">Expired</string>
|
||||
<string name="failed">✗ Failed</string>
|
||||
<string name="follow">follow</string>
|
||||
<string name="follow_back">follow back</string>
|
||||
<string name="functionality_coming_soon">functionality coming soon.</string>
|
||||
<string name="has_not_taken_part_yet">Has not taken part yet</string>
|
||||
<string name="how_many_admins_have_to_approve_a_change">How many admins have to approve a change?</string>
|
||||
<string name="how_many_members_will_it_take_to_sign">How many members will it take to sign?</string>
|
||||
<string name="if_you_are_new_to_torch_or_just_want_to">If you are new to Torch or just want to create a fresh profile</string>
|
||||
<string name="initial_version_label">Initial version label</string>
|
||||
<string name="input_npub_or_nip05">Input npub... or nip05</string>
|
||||
<string name="introduce_yourself">Introduce yourself</string>
|
||||
<string name="invite">Invite</string>
|
||||
<string name="invite_a_friend">Invite a friend</string>
|
||||
<string name="invite_new_member">Invite new member</string>
|
||||
<string name="it_is_cryptographical_secure_and">It is cryptographical secure, and decentralized, putting you in total control of your digital profile</string>
|
||||
<string name="just_you_for_now">Just you for now</string>
|
||||
<string name="keep_the_feed_alive">Keep the feed alive.</string>
|
||||
<string name="key">Key</string>
|
||||
<string name="key_package_management">Key package management</string>
|
||||
<string name="language">Language</string>
|
||||
<string name="learn_more">Learn more</string>
|
||||
<string name="leave_group">Leave group</string>
|
||||
<string name="library">Library</string>
|
||||
<string name="lightning_invoice">Lightning invoice</string>
|
||||
<string name="live">LIVE</string>
|
||||
<string name="live_stream">Live stream</string>
|
||||
<string name="loading">Loading</string>
|
||||
<string name="loading_article">Loading article...</string>
|
||||
<string name="loading_author_information">Loading author information</string>
|
||||
<string name="loading_author_information_2">Loading author information...</string>
|
||||
<string name="loading_information">loading information...</string>
|
||||
<string name="loading_note">Loading note...</string>
|
||||
<string name="loading_stream">Loading stream...</string>
|
||||
<string name="lock_prompt_coming_soon">Lock prompt coming soon.</string>
|
||||
<string name="malformed_note">Malformed note</string>
|
||||
<string name="mantra">Mantra</string>
|
||||
<string name="members">Members</string>
|
||||
<string name="members_2">members</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="name_eg_alan_turing">Name (eg. Alan Turing)</string>
|
||||
<string name="name_eg_group_discussions">Name (eg. Group Discussions)</string>
|
||||
<string name="name_of_artifact">Name of artifact</string>
|
||||
<string name="network_relays">Network relays</string>
|
||||
<string name="new_chat">New chat</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="no_artifacts_exists_in_this_groups_library">No artifacts exists in this groups library.</string>
|
||||
<string name="no_chapters">No chapters.</string>
|
||||
<string name="no_chapters_yet">No chapters yet.</string>
|
||||
<string name="no_chat_message_relays_were_found_for_this">No chat message relays were found for this user.</string>
|
||||
<string name="no_chunks">No chunks.</string>
|
||||
<string name="no_dialects_have_been_defined_in_this_group">No dialects have been defined in this group yet. Add one from the group's detail screen first.</string>
|
||||
<string name="no_dialects_have_been_defined_in_this_group_2">No dialects have been defined in this group.</string>
|
||||
<string name="no_events_were_found">No events were found</string>
|
||||
<string name="no_messages_go_to_a_profile_and_send_them_a">No messages. Go to a profile and send them a message.</string>
|
||||
<string name="no_one_selected_yet">No one selected yet</string>
|
||||
<string name="no_one_to_add_yet">No one to add yet.</string>
|
||||
<string name="no_projects_exists_in_this_group">No projects exists in this group.</string>
|
||||
<string name="no_translations_yet">No translations yet.</string>
|
||||
<string name="no_versions">No versions.</string>
|
||||
<string name="not_now">Not now</string>
|
||||
<string name="nothing_was_created_and_no_key_exists_it_is">Nothing was created and no key exists. It is safe to run it again.</string>
|
||||
<string name="nsec_npub_nip_05_static_address">nsec, npub, nip-05 (static address)</string>
|
||||
<string name="open_chat">Open chat</string>
|
||||
<string name="original">Original</string>
|
||||
<string name="original_text">Original text</string>
|
||||
<string name="original_text_markdown">Original text (markdown)</string>
|
||||
<string name="paid">✓ Paid</string>
|
||||
<string name="paste_the_chapter_s_markdown_blank_lines">Paste the chapter's markdown. Blank lines separate paragraphs into chunks.</string>
|
||||
<string name="pay">Pay</string>
|
||||
<string name="pay_now">Pay now</string>
|
||||
<string name="post">Post</string>
|
||||
<string name="post_functionality_coming_soon">post functionality coming soon.</string>
|
||||
<string name="private_to_you">Private to you</string>
|
||||
<string name="profile">Profile</string>
|
||||
<string name="profile_is_ready">Profile is ready</string>
|
||||
<string name="profile_keys">Profile keys</string>
|
||||
<string name="profiles">Profiles</string>
|
||||
<string name="projects">Projects</string>
|
||||
<string name="proposals">Proposals</string>
|
||||
<string name="propose">Propose</string>
|
||||
<string name="propose_artifact">Propose artifact</string>
|
||||
<string name="propose_chapter">Propose chapter</string>
|
||||
<string name="propose_dialect">Propose dialect</string>
|
||||
<string name="propose_translation">Propose translation</string>
|
||||
<string name="publish_new_key_package">Publish new key package</string>
|
||||
<string name="re_broadcast">Re-broadcast</string>
|
||||
<string name="read_to_the_end_of_the_list_to_sign">Read to the end of the list to sign.</string>
|
||||
<string name="ready_to_sign">Ready to sign</string>
|
||||
<string name="recents">Recents</string>
|
||||
<string name="reindex_events">Reindex events</string>
|
||||
<string name="reposted">reposted</string>
|
||||
<string name="review">Review</string>
|
||||
<string name="review_and_confirm">Review and confirm</string>
|
||||
<string name="review_and_contribute">Review and contribute</string>
|
||||
<string name="review_and_join">Review and join</string>
|
||||
<string name="say_what_now">Say what now?</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="search_for_people_and_chat_with_them_first">Search for people and chat with them first — everyone you know locally shows up here.</string>
|
||||
<string name="search_hashtags">Search hashtags</string>
|
||||
<string name="search_member_functionality">Search member functionality</string>
|
||||
<string name="search_message_functionality_will_be_here">Search message functionality will be here.</string>
|
||||
<string name="see_how_deep_the_rabbit_hole_goes">See how deep the rabbit hole goes</string>
|
||||
<string name="select_a_wallet">Select a wallet</string>
|
||||
<string name="send_message">Send message</string>
|
||||
<string name="share_profile">Share profile</string>
|
||||
<string name="shared_key">Shared key</string>
|
||||
<string name="sign">Sign</string>
|
||||
<string name="sign_in">Sign in</string>
|
||||
<string name="sign_in_to_nsec">Sign in to nsec</string>
|
||||
<string name="sign_in_to_torch_via_nsec_or_remote_signer">Sign in to Torch via nsec, or remote signer</string>
|
||||
<string name="sign_in_with_an_npub">Sign in with an npub</string>
|
||||
<string name="sign_out">Sign out</string>
|
||||
<string name="sign_with_the_group_s_key">Sign with the group's key</string>
|
||||
<string name="signed_their_part">Signed their part</string>
|
||||
<string name="skip_for_now">Skip for now</string>
|
||||
<string name="something_went_wrong">Something went wrong</string>
|
||||
<string name="something_went_wrong_and_we_were_unable_to">Something went wrong and we were unable to sign in to your provided profile. Please try again later.</string>
|
||||
<string name="something_went_wrong_and_we_were_unable_to_2">Something went wrong and we were unable to sign you up. Please try again later.</string>
|
||||
<string name="something_went_wrong_and_we_were_unable_to_3">Something went wrong and we were unable to write a new note. Please try again later.</string>
|
||||
<string name="source_dialect">Source dialect</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="start_a_group_chat">Start a group chat</string>
|
||||
<string name="start_chat">Start chat</string>
|
||||
<string name="start_chat_via_npub_or_nip05">Start chat via npub or nip05</string>
|
||||
<string name="start_key_ceremony">Start key ceremony</string>
|
||||
<string name="startup_error">Startup error</string>
|
||||
<string name="taking_part_with_these_members">Taking part with these members</string>
|
||||
<string name="tap_to_load">Tap to load</string>
|
||||
<string name="tell_friends_to_join_you_so_your_feed_stays">Tell friends to join you so your feed stays lively and fresh.</string>
|
||||
<string name="the_above_will_be_your_new_note">The above will be your new note.</string>
|
||||
<string name="the_above_will_be_your_profile">The above will be your profile.</string>
|
||||
<string name="the_ceremony_was_abandoned">The ceremony was abandoned.</string>
|
||||
<string name="the_group_can_hold_one_key_together_split_so">The group can hold one key together, split so that no single member holds it. Signing with it takes a quorum.</string>
|
||||
<string name="the_group_has_a_shared_key">The group has a shared key.</string>
|
||||
<string name="this_artifact_has_no_version_for_a">This artifact has no version for a translation to be of.</string>
|
||||
<string name="this_artifact_has_no_version_for_a_chapter">This artifact has no version for a chapter to attach to.</string>
|
||||
<string name="this_chapter_has_no_chunks">This chapter has no chunks.</string>
|
||||
<string name="this_decides_who_can_change_the_group_later">This decides who can change the group later. You can't switch afterwards.</string>
|
||||
<string name="this_group_has_no_shared_key_so_it_cannot">This group has no shared key, so it cannot sign them in.</string>
|
||||
<string name="this_group_has_not_been_asked_to_sign">This group has not been asked to sign anything yet.</string>
|
||||
<string name="this_is_fixed_once_the_ceremony_runs">This is fixed once the ceremony runs. Changing it later means generating a new key.</string>
|
||||
<string name="this_is_the_last_thing_the_ceremony_needs">This is the last thing the ceremony needs from you.</string>
|
||||
<string name="this_will_be_shown_when_people_open_the_chat">This will be shown when people open the chat for more details.</string>
|
||||
<string name="this_will_be_shown_when_people_open_your">This will be shown when people open your profile.</string>
|
||||
<string name="this_will_be_the_display_name_for_this_chat">This will be the display name for this chat room.</string>
|
||||
<string name="this_will_be_the_display_name_for_your">This will be the display name for your profile and also important for search.</string>
|
||||
<string name="this_will_give_you_read_only_access_to_the">This will give you read only access to the profile.</string>
|
||||
<string name="this_will_give_you_write_access_to_the">This will give you write access to the profile.</string>
|
||||
<string name="torch_will_be_broadcast_what_you_publish_to">Torch will be broadcast what you publish to a distributed set of relays so that it's decentralized.</string>
|
||||
<string name="translate_chunk">Translate chunk</string>
|
||||
<string name="translate_into_which_dialect">Translate into which dialect?</string>
|
||||
<string name="translated_text">Translated text</string>
|
||||
<string name="translation">Translation</string>
|
||||
<string name="translation_detail">Translation detail</string>
|
||||
<string name="translations">Translations</string>
|
||||
<string name="transmit_note">Transmit note</string>
|
||||
<string name="trending_notes_functionality_coming_soon_in">Trending notes functionality coming soon. In the meantime search for what you are looking for.</string>
|
||||
<string name="try_again">Try again</string>
|
||||
<string name="type_out_what_you_would_like_to_publish">Type out what you would like to publish</string>
|
||||
<string name="unfollow">Unfollow</string>
|
||||
<string name="unsupported_event_kind">Unsupported event kind</string>
|
||||
<string name="untitled_article">Untitled article</string>
|
||||
<string name="url">Url</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="versions">Versions</string>
|
||||
<string name="view_and_accept_invites_you_may_have">View and accept invites you may have received to stay connected with others.</string>
|
||||
<string name="view_invites">View invites</string>
|
||||
<string name="waiting_for_you">Waiting for you</string>
|
||||
<string name="waiting_for_your_signature">Waiting for your signature</string>
|
||||
<string name="we_are_looking_for_your_profile_on_as_many">We are looking for your profile on as many relays as possible. Nostr aims to be decentralized by distributing data to multiple nodse.</string>
|
||||
<string name="we_are_searching_the_internet_to_find_your">We are searching the internet to find your profile and complete sign in.</string>
|
||||
<string name="we_couldn_t_find_the_local_profile_please">We couldn't find the local profile. Please try again later.</string>
|
||||
<string name="we_couldn_t_find_your_nostr_event_please_try">We couldn't find your nostr event. Please try again later.</string>
|
||||
<string name="what_s_your_comment_on_the_below">What's your comment on the below</string>
|
||||
<string name="what_s_your_reply_to_the_above">What's your reply to the above</string>
|
||||
<string name="what_should_people_know_about_you">What should people know about you?</string>
|
||||
<string name="what_vibrations_do_you_want_to_send_out">What vibrations do you want to send out?</string>
|
||||
<string name="what_will_be_discussed_in_this_chat_room">What will be discussed in this chat room.</string>
|
||||
<string name="who_will_you_be_passing_the_aux_to">Who will you be passing the aux to?</string>
|
||||
<string name="you">You</string>
|
||||
<string name="you_and_1_other">You and 1 other</string>
|
||||
<string name="you_are_about_to_create_a_nostr_profile">You are about to create a NOSTR profile.</string>
|
||||
<string name="you_can_still_carry_on_and_invite_people">You can still carry on and invite people later.</string>
|
||||
<string name="you_will_be_in_full_control_of_this_profile">You will be in full control of this profile. If you would like to use it for the long term please remember to backup the profile/keys.</string>
|
||||
<string name="your_profile_is_almost_ready_just_getting_it">Your profile is almost ready... just getting it's first cryptographic signature together.</string>
|
||||
<string name="your_share_of_it_is_on_this_device_only_your">Your share of it is on this device only. Your wallet backup restores it — nobody else's share can.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user