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:
Kgothatso NgakoandClaude Opus 5 committed 2026-09-08 01:38:31 +02:00
1 parent 0304aca62a
commit 419504c982
63 files changed
+1306 -314

No files matched your search

@@ -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>
@@ -52,6 +52,18 @@ import press.mantra.compose.ui.view.state.ActiveProfileUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.change_account
import mantra.composeapp.generated.resources.edit_profile
import mantra.composeapp.generated.resources.key_package_management
import mantra.composeapp.generated.resources.network_relays
import mantra.composeapp.generated.resources.profile
import mantra.composeapp.generated.resources.profile_keys
import mantra.composeapp.generated.resources.share_profile
import mantra.composeapp.generated.resources.sign_out
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.we_couldn_t_find_the_local_profile_please
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -80,7 +92,7 @@ fun ActiveProfileScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Something went wrong")
Text(stringResource(Res.string.something_went_wrong))
}
}
is ActiveProfileUIState.Loaded -> {
@@ -89,7 +101,7 @@ fun ActiveProfileScreen(
TopAppBar(
title = {
Text(
text = "Profile"
text = stringResource(Res.string.profile)
)
},
navigationIcon = {
@@ -177,7 +189,7 @@ fun ActiveProfileScreen(
)
Text(
"Edit profile"
stringResource(Res.string.edit_profile)
)
}
@@ -204,7 +216,7 @@ fun ActiveProfileScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
"Share profile"
stringResource(Res.string.share_profile)
)
}
@@ -236,7 +248,7 @@ fun ActiveProfileScreen(
)
Text(
"Key package management"
stringResource(Res.string.key_package_management)
)
}
}
@@ -261,7 +273,7 @@ fun ActiveProfileScreen(
)
Text(
"Change account"
stringResource(Res.string.change_account)
)
}
}
@@ -285,7 +297,7 @@ fun ActiveProfileScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Profile keys")
Text(stringResource(Res.string.profile_keys))
}
}
@@ -308,7 +320,7 @@ fun ActiveProfileScreen(
)
Text(
"Network relays"
stringResource(Res.string.network_relays)
)
}
}
@@ -331,7 +343,7 @@ fun ActiveProfileScreen(
)
Text(
"Sign out"
stringResource(Res.string.sign_out)
)
}
}
@@ -352,7 +364,7 @@ fun ActiveProfileScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("We couldn't find the local profile. Please try again later.")
Text(stringResource(Res.string.we_couldn_t_find_the_local_profile_please))
}
}
}
@@ -69,6 +69,20 @@ import press.mantra.compose.ui.composable.navigation.routes.ImplementationPendin
import press.mantra.compose.ui.view.model.AddArtifactViewModel
import press.mantra.compose.ui.view.state.AddArtifactUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_artifact_to_the_group_library
import mantra.composeapp.generated.resources.direct_message_detail
import mantra.composeapp.generated.resources.direct_message_functionality_will_be_here
import mantra.composeapp.generated.resources.eg_first_edition
import mantra.composeapp.generated.resources.eg_https_harper_com_2_kill_bird
import mantra.composeapp.generated.resources.eg_to_kill_a_mocking_bird
import mantra.composeapp.generated.resources.initial_version_label
import mantra.composeapp.generated.resources.name_of_artifact
import mantra.composeapp.generated.resources.no_dialects_have_been_defined_in_this_group
import mantra.composeapp.generated.resources.propose_artifact
import mantra.composeapp.generated.resources.source_dialect
import mantra.composeapp.generated.resources.url
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
@@ -205,7 +219,7 @@ fun AddArtifactScreen(
Icons.Default.Add,
contentDescription = "Propose artifact"
)
Text("Propose artifact")
Text(stringResource(Res.string.propose_artifact))
}
}
)
@@ -220,7 +234,7 @@ fun AddArtifactScreen(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Add artifact to the group library")
Text(stringResource(Res.string.add_artifact_to_the_group_library))
if (!addArtifactUIState.canSign) {
Text(
@@ -248,12 +262,12 @@ fun AddArtifactScreen(
},
label = {
Text(
text = "Name of artifact"
text = stringResource(Res.string.name_of_artifact)
)
},
placeholder = {
Text(
text = "eg. To Kill a Mocking Bird"
text = stringResource(Res.string.eg_to_kill_a_mocking_bird)
)
},
)
@@ -275,12 +289,12 @@ fun AddArtifactScreen(
},
label = {
Text(
text = "Url"
text = stringResource(Res.string.url)
)
},
placeholder = {
Text(
text = "eg. https://harper.com/2-kill-Bird"
text = stringResource(Res.string.eg_https_harper_com_2_kill_bird)
)
},
)
@@ -302,21 +316,21 @@ fun AddArtifactScreen(
},
label = {
Text(
text = "Initial version label"
text = stringResource(Res.string.initial_version_label)
)
},
placeholder = {
Text(
text = "eg. First Edition"
text = stringResource(Res.string.eg_first_edition)
)
},
)
Text("Source dialect")
Text(stringResource(Res.string.source_dialect))
if (addArtifactUIState.dialects.isEmpty()) {
Text(
text = "No dialects have been defined in this group yet. Add one from the group's detail screen first.",
text = stringResource(Res.string.no_dialects_have_been_defined_in_this_group),
style = MaterialTheme.typography.bodySmall
)
} else {
@@ -352,13 +366,13 @@ fun AddArtifactScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Direct message detail",
text = stringResource(Res.string.direct_message_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Direct message functionality will be here.",
text = stringResource(Res.string.direct_message_functionality_will_be_here),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -54,6 +54,15 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.AddChapterViewModel
import press.mantra.compose.ui.view.state.AddChapterUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_chapter
import mantra.composeapp.generated.resources.chapter_name
import mantra.composeapp.generated.resources.eg_chapter_1_the_beginning
import mantra.composeapp.generated.resources.original_text_markdown
import mantra.composeapp.generated.resources.paste_the_chapter_s_markdown_blank_lines
import mantra.composeapp.generated.resources.propose_chapter
import mantra.composeapp.generated.resources.this_artifact_has_no_version_for_a_chapter
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -197,7 +206,7 @@ fun AddChapterScreen(
Icons.Default.Add,
contentDescription = "Propose chapter"
)
Text("Propose chapter")
Text(stringResource(Res.string.propose_chapter))
}
}
)
@@ -216,7 +225,7 @@ fun AddChapterScreen(
)
} else if (artifactVersion == null) {
Text(
text = "This artifact has no version for a chapter to attach to.",
text = stringResource(Res.string.this_artifact_has_no_version_for_a_chapter),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error
)
@@ -239,15 +248,15 @@ fun AddChapterScreen(
contentDescription = "Name of the chapter"
)
},
label = { Text("Chapter name") },
placeholder = { Text("eg. Chapter 1 — The Beginning") },
label = { Text(stringResource(Res.string.chapter_name)) },
placeholder = { Text(stringResource(Res.string.eg_chapter_1_the_beginning)) },
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth().weight(1f),
state = originalTextFieldState,
label = { Text("Original text (markdown)") },
placeholder = { Text("Paste the chapter's markdown. Blank lines separate paragraphs into chunks.") },
label = { Text(stringResource(Res.string.original_text_markdown)) },
placeholder = { Text(stringResource(Res.string.paste_the_chapter_s_markdown_blank_lines)) },
)
Text(
@@ -276,7 +285,7 @@ fun AddChapterScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Add chapter",
text = stringResource(Res.string.add_chapter),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -56,6 +56,17 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.AddDialectViewModel
import press.mantra.compose.ui.view.state.AddDialectUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_a_dialect_the_group_can_translate_into
import mantra.composeapp.generated.resources.add_dialect
import mantra.composeapp.generated.resources.country
import mantra.composeapp.generated.resources.dialect_name
import mantra.composeapp.generated.resources.eg_lesotho
import mantra.composeapp.generated.resources.eg_sesotho
import mantra.composeapp.generated.resources.eg_st
import mantra.composeapp.generated.resources.language
import mantra.composeapp.generated.resources.propose_dialect
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -174,7 +185,7 @@ fun AddDialectScreen(
Icons.Default.Add,
contentDescription = "Propose dialect"
)
Text("Propose dialect")
Text(stringResource(Res.string.propose_dialect))
}
}
)
@@ -188,7 +199,7 @@ fun AddDialectScreen(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Add a dialect the group can translate into")
Text(stringResource(Res.string.add_a_dialect_the_group_can_translate_into))
if (!addDialectUIState.canSign) {
Text(
@@ -216,12 +227,12 @@ fun AddDialectScreen(
},
label = {
Text(
text = "Dialect name"
text = stringResource(Res.string.dialect_name)
)
},
placeholder = {
Text(
text = "eg. Sesotho"
text = stringResource(Res.string.eg_sesotho)
)
},
)
@@ -243,12 +254,12 @@ fun AddDialectScreen(
},
label = {
Text(
text = "Country"
text = stringResource(Res.string.country)
)
},
placeholder = {
Text(
text = "eg. Lesotho"
text = stringResource(Res.string.eg_lesotho)
)
},
)
@@ -270,12 +281,12 @@ fun AddDialectScreen(
},
label = {
Text(
text = "Language"
text = stringResource(Res.string.language)
)
},
placeholder = {
Text(
text = "eg. st"
text = stringResource(Res.string.eg_st)
)
},
)
@@ -296,7 +307,7 @@ fun AddDialectScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Add dialect",
text = stringResource(Res.string.add_dialect),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -38,6 +38,11 @@ import press.mantra.compose.ui.view.model.AddMemberToChatRoomConfirmationViewMod
import press.mantra.compose.ui.view.state.AddMemberToChatRoomConfirmationUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.direct_message_detail
import mantra.composeapp.generated.resources.direct_message_functionality_will_be_here
import mantra.composeapp.generated.resources.invite
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -135,7 +140,7 @@ fun AddMemberToChatRoomConfirmationScreen(
modifier = Modifier.weight(1f)
)
Text("Invite")
Text(stringResource(Res.string.invite))
Text(
text = addMemberToChatRoomConfirmationUIState.profile.humanReadableNameOrPubkey()
@@ -170,13 +175,13 @@ fun AddMemberToChatRoomConfirmationScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Direct message detail",
text = stringResource(Res.string.direct_message_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Direct message functionality will be here.",
text = stringResource(Res.string.direct_message_functionality_will_be_here),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -58,6 +58,12 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.AddTranslationArtifactVersionViewModel
import press.mantra.compose.ui.view.state.AddTranslationArtifactVersionUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_translation
import mantra.composeapp.generated.resources.propose_translation
import mantra.composeapp.generated.resources.this_artifact_has_no_version_for_a
import mantra.composeapp.generated.resources.translate_into_which_dialect
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
@@ -201,7 +207,7 @@ fun AddTranslationArtifactVersionScreen(
Icons.Default.Translate,
contentDescription = "Propose translation"
)
Text("Propose translation")
Text(stringResource(Res.string.propose_translation))
}
}
)
@@ -220,13 +226,13 @@ fun AddTranslationArtifactVersionScreen(
)
} else if (artifactVersion == null) {
Text(
text = "This artifact has no version for a translation to be of.",
text = stringResource(Res.string.this_artifact_has_no_version_for_a),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error
)
}
Text("Translate into which dialect?")
Text(stringResource(Res.string.translate_into_which_dialect))
if (addTranslationUIState.dialects.isEmpty()) {
// The only way out of this screen, and it is not on it:
@@ -283,7 +289,7 @@ fun AddTranslationArtifactVersionScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Add translation",
text = stringResource(Res.string.add_translation),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -49,6 +49,19 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.ArtifactDetailViewModel
import press.mantra.compose.ui.view.state.ArtifactDetailUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_chapter
import mantra.composeapp.generated.resources.add_translation
import mantra.composeapp.generated.resources.artifact_detail
import mantra.composeapp.generated.resources.chapters
import mantra.composeapp.generated.resources.details
import mantra.composeapp.generated.resources.no_chapters_yet
import mantra.composeapp.generated.resources.no_translations_yet
import mantra.composeapp.generated.resources.no_versions
import mantra.composeapp.generated.resources.translations
import mantra.composeapp.generated.resources.version
import mantra.composeapp.generated.resources.versions
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -108,12 +121,12 @@ fun ArtifactDetailScreen(
// Chapters
item {
Text(
text = "Chapters",
text = stringResource(Res.string.chapters),
style = MaterialTheme.typography.labelMedium
)
}
if (artifactDetailUIState.chapters.isEmpty()) {
item { Text("No chapters yet.") }
item { Text(stringResource(Res.string.no_chapters_yet)) }
} else {
items(
items = artifactDetailUIState.chapters,
@@ -167,7 +180,7 @@ fun ArtifactDetailScreen(
contentDescription = "Add chapter"
)
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Add chapter")
Text(stringResource(Res.string.add_chapter))
}
}
@@ -176,12 +189,12 @@ fun ArtifactDetailScreen(
// Translations
item {
Text(
text = "Translations",
text = stringResource(Res.string.translations),
style = MaterialTheme.typography.labelMedium
)
}
if (artifactDetailUIState.translations.isEmpty()) {
item { Text("No translations yet.") }
item { Text(stringResource(Res.string.no_translations_yet)) }
} else {
items(
items = artifactDetailUIState.translations,
@@ -232,7 +245,7 @@ fun ArtifactDetailScreen(
contentDescription = "Add translation"
)
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Add translation")
Text(stringResource(Res.string.add_translation))
}
}
@@ -241,7 +254,7 @@ fun ArtifactDetailScreen(
// Details
item {
Text(
text = "Details",
text = stringResource(Res.string.details),
style = MaterialTheme.typography.labelMedium
)
}
@@ -260,12 +273,12 @@ fun ArtifactDetailScreen(
// Versions
item {
Text(
text = "Versions",
text = stringResource(Res.string.versions),
style = MaterialTheme.typography.labelMedium
)
}
if (artifactDetailUIState.versions.isEmpty()) {
item { Text("No versions.") }
item { Text(stringResource(Res.string.no_versions)) }
} else {
items(
items = artifactDetailUIState.versions,
@@ -274,7 +287,7 @@ fun ArtifactDetailScreen(
Card {
ListItem(
headlineContent = { Text(version.versionLabel) },
overlineContent = { Text("Version") }
overlineContent = { Text(stringResource(Res.string.version)) }
)
}
}
@@ -291,7 +304,7 @@ fun ArtifactDetailScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Artifact detail",
text = stringResource(Res.string.artifact_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -39,6 +39,11 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.ChapterDetailViewModel
import press.mantra.compose.ui.view.state.ChapterDetailUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.chapter_detail
import mantra.composeapp.generated.resources.no_chunks
import mantra.composeapp.generated.resources.original_text
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -104,7 +109,7 @@ fun ChapterDetailScreen(
// Original text (markdown, shown as-is).
item {
Text(
text = "Original text",
text = stringResource(Res.string.original_text),
style = MaterialTheme.typography.labelMedium
)
}
@@ -128,7 +133,7 @@ fun ChapterDetailScreen(
)
}
if (chapterDetailUIState.chunks.isEmpty()) {
item { Text("No chunks.") }
item { Text(stringResource(Res.string.no_chunks)) }
} else {
items(
items = chapterDetailUIState.chunks,
@@ -163,7 +168,7 @@ fun ChapterDetailScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Chapter detail",
text = stringResource(Res.string.chapter_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -30,6 +30,15 @@ import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.view.model.ChatRoomCreationViewModel
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.choose_who_to_chat_with
import mantra.composeapp.generated.resources.enter_the_name_you_want_to_use_for_your
import mantra.composeapp.generated.resources.name_eg_group_discussions
import mantra.composeapp.generated.resources.this_will_be_shown_when_people_open_the_chat
import mantra.composeapp.generated.resources.this_will_be_the_display_name_for_this_chat
import mantra.composeapp.generated.resources.what_should_people_know_about_you
import mantra.composeapp.generated.resources.what_will_be_discussed_in_this_chat_room
@Composable
fun ChatRoomCreationScreen(
@@ -72,13 +81,13 @@ fun ChatRoomCreationScreen(
),
label = {
Text(
text = "Name (eg. Group Discussions)",
text = stringResource(Res.string.name_eg_group_discussions),
maxLines = 1,
)
},
placeholder = {
Text(
text = "Enter the name you want to use for your group",
text = stringResource(Res.string.enter_the_name_you_want_to_use_for_your),
maxLines = 1,
)
},
@@ -91,7 +100,7 @@ fun ChatRoomCreationScreen(
)
Text(
text = "This will be the display name for this chat room.",
text = stringResource(Res.string.this_will_be_the_display_name_for_this_chat),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center
)
@@ -116,14 +125,14 @@ fun ChatRoomCreationScreen(
),
label = {
Text(
text = "What will be discussed in this chat room.",
text = stringResource(Res.string.what_will_be_discussed_in_this_chat_room),
maxLines = 1,
)
},
placeholder = {
Text(
text = "What should people know about you?",
text = stringResource(Res.string.what_should_people_know_about_you),
maxLines = 1,
)
},
@@ -136,7 +145,7 @@ fun ChatRoomCreationScreen(
)
Text(
text = "This will be shown when people open the chat for more details.",
text = stringResource(Res.string.this_will_be_shown_when_people_open_the_chat),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center
)
@@ -151,7 +160,7 @@ fun ChatRoomCreationScreen(
}
) {
Text(
"Choose who to chat with"
stringResource(Res.string.choose_who_to_chat_with)
)
}
}
@@ -69,6 +69,26 @@ import press.mantra.compose.ui.composable.navigation.routes.AddArtifactRoute
import press.mantra.compose.ui.composable.navigation.routes.AddDialectRoute
import press.mantra.compose.ui.composable.navigation.routes.ArtifactDetailRoute
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_artifact_to_library
import mantra.composeapp.generated.resources.add_dialect
import mantra.composeapp.generated.resources.create_project
import mantra.composeapp.generated.resources.delete_group
import mantra.composeapp.generated.resources.dialects
import mantra.composeapp.generated.resources.direct_message_detail
import mantra.composeapp.generated.resources.direct_message_functionality_will_be_here
import mantra.composeapp.generated.resources.invite_new_member
import mantra.composeapp.generated.resources.leave_group
import mantra.composeapp.generated.resources.library
import mantra.composeapp.generated.resources.members_2
import mantra.composeapp.generated.resources.no_artifacts_exists_in_this_groups_library
import mantra.composeapp.generated.resources.no_dialects_have_been_defined_in_this_group_2
import mantra.composeapp.generated.resources.no_projects_exists_in_this_group
import mantra.composeapp.generated.resources.projects
import mantra.composeapp.generated.resources.proposals
import mantra.composeapp.generated.resources.reindex_events
import mantra.composeapp.generated.resources.shared_key
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -144,14 +164,14 @@ fun ChatRoomDetailScreen(
item {
// Artifacts
Text(
text = "Library",
text = stringResource(Res.string.library),
style = MaterialTheme.typography.labelMedium
)
}
if (chatRoomDetailUIState.artifacts.isEmpty()) {
item {
Text("No artifacts exists in this groups library.")
Text(stringResource(Res.string.no_artifacts_exists_in_this_groups_library))
}
} else {
items(
@@ -217,7 +237,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add artifact to library")
Text(stringResource(Res.string.add_artifact_to_library))
}
}
@@ -228,14 +248,14 @@ fun ChatRoomDetailScreen(
item {
// Dialects
Text(
text = "Dialects",
text = stringResource(Res.string.dialects),
style = MaterialTheme.typography.labelMedium
)
}
if (chatRoomDetailUIState.dialects.isEmpty()) {
item {
Text("No dialects have been defined in this group.")
Text(stringResource(Res.string.no_dialects_have_been_defined_in_this_group_2))
}
} else {
items(
@@ -283,7 +303,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add dialect")
Text(stringResource(Res.string.add_dialect))
}
}
@@ -296,13 +316,13 @@ fun ChatRoomDetailScreen(
item {
// Artifacts
Text(
text = "Projects",
text = stringResource(Res.string.projects),
style = MaterialTheme.typography.labelMedium
)
}
item {
Text("No projects exists in this group.")
Text(stringResource(Res.string.no_projects_exists_in_this_group))
}
item {
@@ -326,7 +346,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Create project")
Text(stringResource(Res.string.create_project))
}
}
@@ -336,7 +356,7 @@ fun ChatRoomDetailScreen(
item {
Text(
text = "members",
text = stringResource(Res.string.members_2),
style = MaterialTheme.typography.labelMedium
)
}
@@ -365,7 +385,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Shared key")
Text(stringResource(Res.string.shared_key))
}
}
}
@@ -399,7 +419,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Proposals")
Text(stringResource(Res.string.proposals))
}
}
@@ -426,7 +446,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Invite new member")
Text(stringResource(Res.string.invite_new_member))
}
}
@@ -503,7 +523,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Leave group")
Text(stringResource(Res.string.leave_group))
}
// What it actually does: sets leftGroupAt and posts a line to
@@ -544,7 +564,7 @@ fun ChatRoomDetailScreen(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Delete group")
Text(stringResource(Res.string.delete_group))
}
// A soft delete: it sets deletedAt on the local row. Saying
@@ -596,13 +616,13 @@ fun ChatRoomDetailScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Direct message detail",
text = stringResource(Res.string.direct_message_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Direct message functionality will be here.",
text = stringResource(Res.string.direct_message_functionality_will_be_here),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -663,7 +683,7 @@ private fun ReindexMarmotGroupEventsButton(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Reindex events")
Text(stringResource(Res.string.reindex_events))
}
when (reindexState) {
@@ -58,6 +58,12 @@ import press.mantra.compose.ui.view.state.ChatRoomMessagingUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.creating_new_chat
import mantra.composeapp.generated.resources.direct_message_detail
import mantra.composeapp.generated.resources.direct_message_functionality_will_be_here
import mantra.composeapp.generated.resources.say_what_now
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -280,7 +286,7 @@ fun ChatRoomMessagingScreen(
text = if (directMessageRecipient != null) {
"Private message to ${chatMessageListViewModel.nameFor(directMessageRecipient.participantPublicKey)}"
} else {
"Say what now?"
stringResource(Res.string.say_what_now)
}
)
},
@@ -380,13 +386,13 @@ fun ChatRoomMessagingScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Direct message detail",
text = stringResource(Res.string.direct_message_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Direct message functionality will be here.",
text = stringResource(Res.string.direct_message_functionality_will_be_here),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -413,7 +419,7 @@ fun ChatRoomMessagingScreen(
)
Text(
text = "Creating new chat.",
text = stringResource(Res.string.creating_new_chat),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -37,6 +37,28 @@ import press.mantra.compose.ui.theme.LocalExtendedColors
import press.mantra.compose.ui.view.model.CreateProfileViewModel
import press.mantra.compose.ui.view.state.CreateProfileUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.after_this_there_is_no_turning_back
import mantra.composeapp.generated.resources.bio
import mantra.composeapp.generated.resources.create_profile
import mantra.composeapp.generated.resources.end_this
import mantra.composeapp.generated.resources.enter_the_name_you_want_to_use_for_your_2
import mantra.composeapp.generated.resources.introduce_yourself
import mantra.composeapp.generated.resources.it_is_cryptographical_secure_and
import mantra.composeapp.generated.resources.name
import mantra.composeapp.generated.resources.name_eg_alan_turing
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.profile_is_ready
import mantra.composeapp.generated.resources.see_how_deep_the_rabbit_hole_goes
import mantra.composeapp.generated.resources.something_went_wrong_and_we_were_unable_to_2
import mantra.composeapp.generated.resources.start
import mantra.composeapp.generated.resources.the_above_will_be_your_profile
import mantra.composeapp.generated.resources.this_will_be_shown_when_people_open_your
import mantra.composeapp.generated.resources.this_will_be_the_display_name_for_your
import mantra.composeapp.generated.resources.what_should_people_know_about_you
import mantra.composeapp.generated.resources.you_are_about_to_create_a_nostr_profile
import mantra.composeapp.generated.resources.you_will_be_in_full_control_of_this_profile
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -73,18 +95,18 @@ fun CreateProfileScreen(
is CreateProfileUIState.Declaration -> {
Text(
"Create profile",
stringResource(Res.string.create_profile),
style = MaterialTheme.typography.headlineSmall
)
Text(
"You are about to create a NOSTR profile.",
stringResource(Res.string.you_are_about_to_create_a_nostr_profile),
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center
)
Text(
"It is cryptographical secure, and decentralized, putting you in total control of your digital profile",
stringResource(Res.string.it_is_cryptographical_secure_and),
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center
)
@@ -100,13 +122,13 @@ fun CreateProfileScreen(
}
) {
Text(
text = "Start"
text = stringResource(Res.string.start)
)
}
}
is CreateProfileUIState.InputPrompt -> {
Text(
"Create profile",
stringResource(Res.string.create_profile),
style = MaterialTheme.typography.headlineSmall
)
@@ -134,13 +156,13 @@ fun CreateProfileScreen(
),
label = {
Text(
text = "Name (eg. Alan Turing)",
text = stringResource(Res.string.name_eg_alan_turing),
maxLines = 1,
)
},
placeholder = {
Text(
text = "Enter the name you want to use for your profile",
text = stringResource(Res.string.enter_the_name_you_want_to_use_for_your_2),
maxLines = 1,
)
},
@@ -153,7 +175,7 @@ fun CreateProfileScreen(
)
Text(
text = "This will be the display name for your profile and also important for search.",
text = stringResource(Res.string.this_will_be_the_display_name_for_your),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center
)
@@ -178,14 +200,14 @@ fun CreateProfileScreen(
),
label = {
Text(
text = "Introduce yourself",
text = stringResource(Res.string.introduce_yourself),
maxLines = 1,
)
},
placeholder = {
Text(
text = "What should people know about you?",
text = stringResource(Res.string.what_should_people_know_about_you),
maxLines = 1,
)
},
@@ -198,7 +220,7 @@ fun CreateProfileScreen(
)
Text(
text = "This will be shown when people open your profile.",
text = stringResource(Res.string.this_will_be_shown_when_people_open_your),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center
)
@@ -220,7 +242,7 @@ fun CreateProfileScreen(
}
) {
Text(
"Next"
stringResource(Res.string.next)
)
}
@@ -228,7 +250,7 @@ fun CreateProfileScreen(
is CreateProfileUIState.ConfirmInput -> {
Text(
text = "Name",
text = stringResource(Res.string.name),
style = MaterialTheme.typography.labelLarge
)
@@ -239,7 +261,7 @@ fun CreateProfileScreen(
)
Text(
text = "Bio",
text = stringResource(Res.string.bio),
style = MaterialTheme.typography.labelLarge
)
@@ -252,7 +274,7 @@ fun CreateProfileScreen(
Text(
text = "The above will be your profile.",
text = stringResource(Res.string.the_above_will_be_your_profile),
style = MaterialTheme.typography.bodySmall
)
@@ -261,7 +283,7 @@ fun CreateProfileScreen(
)
Text(
text = "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.",
text = stringResource(Res.string.you_will_be_in_full_control_of_this_profile),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
@@ -277,7 +299,7 @@ fun CreateProfileScreen(
}
) {
Text(
text = "Create profile"
text = stringResource(Res.string.create_profile)
)
}
}
@@ -288,7 +310,7 @@ fun CreateProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Something went wrong and we were unable to sign you up. Please try again later.",
text = stringResource(Res.string.something_went_wrong_and_we_were_unable_to_2),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -308,13 +330,13 @@ fun CreateProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Profile is ready",
text = stringResource(Res.string.profile_is_ready),
style = MaterialTheme.typography.headlineLarge,
textAlign = TextAlign.Center
)
Text(
text = "After this there is no turning back."
text = stringResource(Res.string.after_this_there_is_no_turning_back)
)
Button(
@@ -327,7 +349,7 @@ fun CreateProfileScreen(
}
) {
Text(
text = "See how deep the rabbit hole goes"
text = stringResource(Res.string.see_how_deep_the_rabbit_hole_goes)
)
}
@@ -348,7 +370,7 @@ fun CreateProfileScreen(
}
) {
Text(
text = "end this"
text = stringResource(Res.string.end_this)
)
}
Spacer(
@@ -39,6 +39,10 @@ import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.back
import mantra.composeapp.generated.resources.not_now
/**
* The frame every ChillDKG approval screen sits in: the view model, the states
@@ -149,7 +153,7 @@ internal fun DkgApprovalScaffold(
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center
)
TextButton(onClick = onDone) { Text(text = "Back") }
TextButton(onClick = onDone) { Text(text = stringResource(Res.string.back)) }
}
return@Scaffold
@@ -181,7 +185,7 @@ internal fun DkgApprovalScaffold(
onClick = onDone,
enabled = !isActionPending
) {
Text(text = "Not now")
Text(text = stringResource(Res.string.not_now))
}
Button(
@@ -77,6 +77,24 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.create_the_admins_group
import mantra.composeapp.generated.resources.how_many_members_will_it_take_to_sign
import mantra.composeapp.generated.resources.key
import mantra.composeapp.generated.resources.members
import mantra.composeapp.generated.resources.nothing_was_created_and_no_key_exists_it_is
import mantra.composeapp.generated.resources.review_and_confirm
import mantra.composeapp.generated.resources.review_and_contribute
import mantra.composeapp.generated.resources.review_and_join
import mantra.composeapp.generated.resources.shared_key
import mantra.composeapp.generated.resources.start_key_ceremony
import mantra.composeapp.generated.resources.the_ceremony_was_abandoned
import mantra.composeapp.generated.resources.the_group_can_hold_one_key_together_split_so
import mantra.composeapp.generated.resources.the_group_has_a_shared_key
import mantra.composeapp.generated.resources.this_is_fixed_once_the_ceremony_runs
import mantra.composeapp.generated.resources.try_again
import mantra.composeapp.generated.resources.your_share_of_it_is_on_this_device_only_your
/**
* The shared-key ceremony: a ChillDKG ritual run across the group's NIP-17
@@ -169,9 +187,9 @@ fun DkgRitualScreen(
Icon(Icons.Default.Key, contentDescription = Decorative)
Text(
text = when (pending) {
DkgApprovalStep.HOST_KEY -> "Review and join"
DkgApprovalStep.ROUND_1 -> "Review and contribute"
DkgApprovalStep.ROUND_2 -> "Review and confirm"
DkgApprovalStep.HOST_KEY -> stringResource(Res.string.review_and_join)
DkgApprovalStep.ROUND_1 -> stringResource(Res.string.review_and_contribute)
DkgApprovalStep.ROUND_2 -> stringResource(Res.string.review_and_confirm)
}
)
}
@@ -197,7 +215,7 @@ fun DkgRitualScreen(
}
Text(
text = if (session == null) "Start key ceremony" else "Try again"
text = if (session == null) stringResource(Res.string.start_key_ceremony) else stringResource(Res.string.try_again)
)
}
},
@@ -222,7 +240,7 @@ fun DkgRitualScreen(
) {
if (session == null) {
Text(
text = "The group can hold one key together, split so that no single member holds it. Signing with it takes a quorum.",
text = stringResource(Res.string.the_group_can_hold_one_key_together_split_so),
style = MaterialTheme.typography.bodyMedium
)
@@ -272,7 +290,7 @@ fun DkgRitualScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Shared key",
text = stringResource(Res.string.shared_key),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -336,12 +354,12 @@ private fun RitualProgress(
) {
Icon(Icons.Default.ErrorOutline, contentDescription = Decorative)
Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)) {
Text("The ceremony was abandoned.", style = MaterialTheme.typography.titleSmall)
Text(stringResource(Res.string.the_ceremony_was_abandoned), style = MaterialTheme.typography.titleSmall)
session.failureReason?.let {
Text(it, style = MaterialTheme.typography.bodyMedium)
}
Text(
"Nothing was created and no key exists. It is safe to run it again.",
stringResource(Res.string.nothing_was_created_and_no_key_exists_it_is),
style = MaterialTheme.typography.labelMedium
)
}
@@ -406,13 +424,13 @@ private fun RitualProgress(
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.CheckCircle, contentDescription = Decorative)
Text("The group has a shared key.", style = MaterialTheme.typography.titleSmall)
Text(stringResource(Res.string.the_group_has_a_shared_key), style = MaterialTheme.typography.titleSmall)
}
session.thresholdPublicKey?.let { thresholdPublicKey ->
val clipboardManager = LocalClipboardManager.current
Text(text = "Key", style = MaterialTheme.typography.labelMedium)
Text(text = stringResource(Res.string.key), style = MaterialTheme.typography.labelMedium)
Row(
modifier = Modifier.fillMaxWidth(),
@@ -445,7 +463,7 @@ private fun RitualProgress(
}
Text(
text = "Your share of it is on this device only. Your wallet backup restores it — nobody else's share can.",
text = stringResource(Res.string.your_share_of_it_is_on_this_device_only_your),
style = MaterialTheme.typography.labelMedium
)
@@ -476,7 +494,7 @@ private fun RitualProgress(
} else {
Icon(Icons.Default.Groups, contentDescription = Decorative)
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space100))
Text(text = "Create the #admins group")
Text(text = stringResource(Res.string.create_the_admins_group))
}
}
}
@@ -506,7 +524,7 @@ private fun RitualRoster(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Text(text = "Members", style = MaterialTheme.typography.titleSmall)
Text(text = stringResource(Res.string.members), style = MaterialTheme.typography.titleSmall)
members
.sortedBy { it.participant.participantPublicKey }
@@ -616,7 +634,7 @@ private fun QuorumStepper(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space50)
) {
Text(
text = "How many members will it take to sign?",
text = stringResource(Res.string.how_many_members_will_it_take_to_sign),
style = MaterialTheme.typography.titleSmall
)
@@ -646,7 +664,7 @@ private fun QuorumStepper(
}
Text(
text = "This is fixed once the ceremony runs. Changing it later means generating a new key.",
text = stringResource(Res.string.this_is_fixed_once_the_ceremony_runs),
style = MaterialTheme.typography.labelMedium
)
}
@@ -15,6 +15,10 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.taking_part_with_these_members
import mantra.composeapp.generated.resources.you
/**
* Asks whether to contribute to the key itself.
@@ -69,7 +73,7 @@ fun DkgRound1ApprovalScreen(
}
Text(
text = "Taking part with these members",
text = stringResource(Res.string.taking_part_with_these_members),
style = MaterialTheme.typography.titleSmall
)
@@ -82,7 +86,7 @@ fun DkgRound1ApprovalScreen(
Text(
text = if (key == activeUserPublicKey) {
"You"
stringResource(Res.string.you)
} else {
member.profile?.humanReadableNameOrPubkey() ?: key.take(12)
},
@@ -15,6 +15,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.this_is_the_last_thing_the_ceremony_needs
/**
* Asks whether to confirm the combined result.
@@ -74,7 +77,7 @@ fun DkgRound2ApprovalScreen(
}
Text(
text = "This is the last thing the ceremony needs from you.",
text = stringResource(Res.string.this_is_the_last_thing_the_ceremony_needs),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -58,6 +58,16 @@ import press.mantra.compose.ui.view.model.FrostSigningViewModel
import press.mantra.compose.ui.view.state.FrostSigningUIState
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.don_t_sign
import mantra.composeapp.generated.resources.has_not_taken_part_yet
import mantra.composeapp.generated.resources.members
import mantra.composeapp.generated.resources.read_to_the_end_of_the_list_to_sign
import mantra.composeapp.generated.resources.ready_to_sign
import mantra.composeapp.generated.resources.sign
import mantra.composeapp.generated.resources.sign_with_the_group_s_key
import mantra.composeapp.generated.resources.signed_their_part
/**
* One signing session, and the member's decision about it.
@@ -105,7 +115,7 @@ fun FrostSigningScreen(
TopAppBar(
title = {
Text(
text = "Sign with the group's key",
text = stringResource(Res.string.sign_with_the_group_s_key),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
@@ -174,7 +184,7 @@ fun FrostSigningScreen(
HorizontalDivider()
Text(
text = "Members",
text = stringResource(Res.string.members),
style = MaterialTheme.typography.labelMedium
)
@@ -224,9 +234,9 @@ fun FrostSigningScreen(
supportingContent = {
Text(
text = when {
member in state.signed -> "Signed their part"
member in state.offeredNonce -> "Ready to sign"
else -> "Has not taken part yet"
member in state.signed -> stringResource(Res.string.signed_their_part)
member in state.offeredNonce -> stringResource(Res.string.ready_to_sign)
else -> stringResource(Res.string.has_not_taken_part_yet)
}
)
}
@@ -260,7 +270,7 @@ fun FrostSigningScreen(
if (readable && !seenEverything) {
Text(
text = "Read to the end of the list to sign.",
text = stringResource(Res.string.read_to_the_end_of_the_list_to_sign),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -278,7 +288,7 @@ fun FrostSigningScreen(
) {
Icon(Icons.Default.Draw, contentDescription = Decorative)
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Sign")
Text(stringResource(Res.string.sign))
}
// Declining stays available whatever the screen could
@@ -293,7 +303,7 @@ fun FrostSigningScreen(
enabled = !frostSigningViewModel.isActionPending.value,
onClick = { frostSigningViewModel.decline(onNavigateBack) }
) {
Text("Don't sign")
Text(stringResource(Res.string.don_t_sign))
}
}
}
@@ -57,6 +57,11 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.mantra
import mantra.composeapp.generated.resources.new_chat
import mantra.composeapp.generated.resources.something_went_wrong
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -96,7 +101,7 @@ fun HomeScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Something went wrong"
text = stringResource(Res.string.something_went_wrong)
)
Spacer(
@@ -122,7 +127,7 @@ fun HomeScreen(
// the other, and is left alone -- it goes on the wire to relay
// operators, so it is a network identity question rather than
// a content one.
Text("Mantra")
Text(stringResource(Res.string.mantra))
},
navigationIcon = {
IconButton(
@@ -168,7 +173,7 @@ fun HomeScreen(
)
},
text = {
Text("New chat")
Text(stringResource(Res.string.new_chat))
}
)
}
@@ -44,6 +44,12 @@ import press.mantra.compose.ui.view.model.KeyPackageManagementViewModel
import press.mantra.compose.ui.view.state.KeyPackageManagementUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.key_package_management
import mantra.composeapp.generated.resources.publish_new_key_package
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.we_couldn_t_find_the_local_profile_please
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -72,7 +78,7 @@ fun KeyPackageManagementScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Something went wrong")
Text(stringResource(Res.string.something_went_wrong))
}
}
is KeyPackageManagementUIState.Loaded -> {
@@ -81,7 +87,7 @@ fun KeyPackageManagementScreen(
TopAppBar(
title = {
Text(
text = "Key package management"
text = stringResource(Res.string.key_package_management)
)
},
navigationIcon = {
@@ -123,7 +129,7 @@ fun KeyPackageManagementScreen(
)
Text(
text = "Publish new key package"
text = stringResource(Res.string.publish_new_key_package)
)
}
}
@@ -213,7 +219,7 @@ fun KeyPackageManagementScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("We couldn't find the local profile. Please try again later.")
Text(stringResource(Res.string.we_couldn_t_find_the_local_profile_please))
}
}
}
@@ -20,6 +20,15 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.create_profile
import mantra.composeapp.generated.resources.if_you_are_new_to_torch_or_just_want_to
import mantra.composeapp.generated.resources.keep_the_feed_alive
import mantra.composeapp.generated.resources.learn_more
import mantra.composeapp.generated.resources.mantra
import mantra.composeapp.generated.resources.sign_in
import mantra.composeapp.generated.resources.sign_in_to_torch_via_nsec_or_remote_signer
@Composable
fun LandingScreen(
@@ -37,19 +46,19 @@ fun LandingScreen(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Mantra",
text = stringResource(Res.string.mantra),
style = MaterialTheme.typography.headlineLarge
)
Text(
text = "Keep the feed alive."
text = stringResource(Res.string.keep_the_feed_alive)
)
TextButton(
onClick = onNavigateToLearnMore
) {
Text(
text = "Learn more",
text = stringResource(Res.string.learn_more),
style = MaterialTheme.typography.labelLarge,
)
}
@@ -63,13 +72,13 @@ fun LandingScreen(
) {
Text(
"Sign in",
stringResource(Res.string.sign_in),
style = MaterialTheme.typography.bodyLarge
)
}
Text(
text = "Sign in to Torch via nsec, or remote signer",
text = stringResource(Res.string.sign_in_to_torch_via_nsec_or_remote_signer),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
@@ -83,13 +92,13 @@ fun LandingScreen(
onClick = onNavigateToCreateProfile
) {
Text(
"Create profile",
stringResource(Res.string.create_profile),
style = MaterialTheme.typography.bodyLarge
)
}
Text(
text = "If you are new to Torch or just want to create a fresh profile",
text = stringResource(Res.string.if_you_are_new_to_torch_or_just_want_to),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
@@ -32,6 +32,12 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.functionality_coming_soon
import mantra.composeapp.generated.resources.post_functionality_coming_soon
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.we_couldn_t_find_your_nostr_event_please_try
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -63,7 +69,7 @@ fun NostrEventDetailScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Something went wrong")
Text(stringResource(Res.string.something_went_wrong))
}
}
is NostrEventDetailUIState.Loaded -> {
@@ -98,7 +104,7 @@ fun NostrEventDetailScreen(
) {
Text(feedListUIState.localNostrEvent.nostrEvent.content)
Text("post functionality coming soon.")
Text(stringResource(Res.string.post_functionality_coming_soon))
}
}
else -> {
@@ -113,7 +119,7 @@ fun NostrEventDetailScreen(
) {
Text(feedListUIState.localNostrEvent.nostrEvent.content)
Text("functionality coming soon.")
Text(stringResource(Res.string.functionality_coming_soon))
}
}
}
@@ -133,7 +139,7 @@ fun NostrEventDetailScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("We couldn't find your nostr event. Please try again later.")
Text(stringResource(Res.string.we_couldn_t_find_your_nostr_event_please_try))
}
}
}
@@ -55,6 +55,13 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.ProposalListViewModel
import press.mantra.compose.ui.view.state.ProposalListUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.everything_else
import mantra.composeapp.generated.resources.proposals
import mantra.composeapp.generated.resources.review
import mantra.composeapp.generated.resources.this_group_has_not_been_asked_to_sign
import mantra.composeapp.generated.resources.waiting_for_you
/**
* Everything the group has asked its shared key to sign.
@@ -102,7 +109,7 @@ fun ProposalListScreen(
TopAppBar(
title = {
Text(
text = "Proposals",
text = stringResource(Res.string.proposals),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
@@ -151,7 +158,7 @@ fun ProposalListScreen(
item {
Text(
modifier = Modifier.fillMaxWidth().padding(top = MaterialTheme.spacing.space600),
text = "This group has not been asked to sign anything yet.",
text = stringResource(Res.string.this_group_has_not_been_asked_to_sign),
textAlign = TextAlign.Center
)
}
@@ -160,7 +167,7 @@ fun ProposalListScreen(
if (state.waitingForYou.isNotEmpty()) {
item {
Text(
text = "Waiting for you",
text = stringResource(Res.string.waiting_for_you),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.primary
)
@@ -181,7 +188,7 @@ fun ProposalListScreen(
if (state.waitingForYou.isNotEmpty()) {
item {
Text(
text = "Everything else",
text = stringResource(Res.string.everything_else),
style = MaterialTheme.typography.labelMedium
)
}
@@ -296,7 +303,7 @@ private fun ProposalCard(
// it saying what it said there.
if (proposal.awaitsYou) {
Text(
text = "Review",
text = stringResource(Res.string.review),
style = MaterialTheme.typography.labelLarge,
color = cardContentColor
)
@@ -41,6 +41,11 @@ import press.mantra.compose.ui.view.model.SearchMemberToAddToChatRoomViewModel
import press.mantra.compose.ui.view.state.SearchMemberToAddToChatRoomUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.currently_no_contacts_please_search_and_chat
import mantra.composeapp.generated.resources.search_member_functionality
import mantra.composeapp.generated.resources.search_message_functionality_will_be_here
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -110,7 +115,7 @@ fun SearchMemberToAddToChatRoomScreen(
)
Text(
modifier = Modifier.padding(MaterialTheme.spacing.space250),
text = "Currently no contacts. Please search and chat with a few people.",
text = stringResource(Res.string.currently_no_contacts_please_search_and_chat),
textAlign = TextAlign.Center
)
@@ -182,13 +187,13 @@ fun SearchMemberToAddToChatRoomScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Search member functionality",
text = stringResource(Res.string.search_member_functionality),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Search message functionality will be here.",
text = stringResource(Res.string.search_message_functionality_will_be_here),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -55,6 +55,12 @@ import press.mantra.compose.ui.view.model.SearchResultViewModel
import press.mantra.compose.ui.view.state.SearchResultListUIState
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.no_events_were_found
import mantra.composeapp.generated.resources.profiles
import mantra.composeapp.generated.resources.search
import mantra.composeapp.generated.resources.something_went_wrong
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -109,7 +115,7 @@ fun SearchResultScreen(
enabled = false,
expanded = expanded,
onExpandedChange = { expanded = it },
placeholder = { Text("Search") },
placeholder = { Text(stringResource(Res.string.search)) },
leadingIcon = {
if (expanded) {
IconButton(
@@ -200,7 +206,7 @@ fun SearchResultScreen(
) {
when(SearchResultType.entries[pageIndex]) {
SearchResultType.Profiles -> {
Text("Profiles")
Text(stringResource(Res.string.profiles))
}
}
@@ -214,7 +220,7 @@ fun SearchResultScreen(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -229,7 +235,7 @@ fun SearchResultScreen(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "No events were found",
text = stringResource(Res.string.no_events_were_found),
)
}
} else {
@@ -63,6 +63,13 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.SearchViewModel
import press.mantra.compose.ui.view.state.SearchUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.profiles
import mantra.composeapp.generated.resources.recents
import mantra.composeapp.generated.resources.search
import mantra.composeapp.generated.resources.search_hashtags
import mantra.composeapp.generated.resources.trending_notes_functionality_coming_soon_in
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -117,7 +124,7 @@ fun SearchScreen(
},
expanded = expanded,
onExpandedChange = { expanded = it },
placeholder = { Text("Search") },
placeholder = { Text(stringResource(Res.string.search)) },
leadingIcon = {
if (expanded) {
IconButton(
@@ -156,7 +163,7 @@ fun SearchScreen(
},
supportingContent = {
Text(
text = "Search"
text = stringResource(Res.string.search)
)
},
leadingContent = {
@@ -196,7 +203,7 @@ fun SearchScreen(
headlineContent = { Text(textFieldState.text.toString()) },
supportingContent = {
Text(
text = "Search hashtags"
text = stringResource(Res.string.search_hashtags)
)
},
leadingContent = {
@@ -289,7 +296,7 @@ fun SearchScreen(
modifier = Modifier.padding(MaterialTheme.spacing.space125),
) {
Text(
text = "Profiles",
text = stringResource(Res.string.profiles),
style = MaterialTheme.typography.titleMedium
)
}
@@ -344,7 +351,7 @@ fun SearchScreen(
modifier = Modifier.padding(MaterialTheme.spacing.space125),
) {
Text(
text = "Recents",
text = stringResource(Res.string.recents),
style = MaterialTheme.typography.titleMedium
)
}
@@ -404,7 +411,7 @@ fun SearchScreen(
title = {}
)
Text(
text = "Trending notes functionality coming soon. In the meantime search for what you are looking for.",
text = stringResource(Res.string.trending_notes_functionality_coming_soon_in),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -43,6 +43,13 @@ import press.mantra.compose.ui.view.model.SelectChatRoomMembersViewModel
import press.mantra.compose.ui.view.state.SelectChatRoomMembersUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.no_one_selected_yet
import mantra.composeapp.generated.resources.no_one_to_add_yet
import mantra.composeapp.generated.resources.search_for_people_and_chat_with_them_first
import mantra.composeapp.generated.resources.you_can_still_carry_on_and_invite_people
/**
* Second step of group creation: pick who is in the group.
@@ -120,7 +127,7 @@ fun SelectChatRoomMembersScreen(
text = if (selectedCount > 0) {
"Next with $selectedCount"
} else {
"Next"
stringResource(Res.string.next)
}
)
}
@@ -131,7 +138,7 @@ fun SelectChatRoomMembersScreen(
text = if (selectedCount > 0) {
"$selectedCount selected"
} else {
"No one selected yet"
stringResource(Res.string.no_one_selected_yet)
},
style = MaterialTheme.typography.labelLarge
)
@@ -153,19 +160,19 @@ fun SelectChatRoomMembersScreen(
)
Text(
text = "No one to add yet.",
text = stringResource(Res.string.no_one_to_add_yet),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Search for people and chat with them first — everyone you know locally shows up here.",
text = stringResource(Res.string.search_for_people_and_chat_with_them_first),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
Text(
text = "You can still carry on and invite people later.",
text = stringResource(Res.string.you_can_still_carry_on_and_invite_people),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -57,6 +57,14 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.create_chat
import mantra.composeapp.generated.resources.how_many_admins_have_to_approve_a_change
import mantra.composeapp.generated.resources.just_you_for_now
import mantra.composeapp.generated.resources.open_chat
import mantra.composeapp.generated.resources.this_decides_who_can_change_the_group_later
import mantra.composeapp.generated.resources.you_and_1_other
/**
* Last step of group creation: convenient (one admin) or robust (everyone
@@ -149,9 +157,9 @@ fun SelectChatRoomTypeScreen(
Text(
text = if (selectChatRoomTypeViewModel.createdChatRoomId.value != null) {
"Open chat"
stringResource(Res.string.open_chat)
} else {
"Create chat"
stringResource(Res.string.create_chat)
}
)
}
@@ -160,8 +168,8 @@ fun SelectChatRoomTypeScreen(
Text(
modifier = Modifier.padding(start = MaterialTheme.spacing.space200),
text = when (selectChatRoomTypeUIState.members.size) {
0 -> "Just you for now"
1 -> "You and 1 other"
0 -> stringResource(Res.string.just_you_for_now)
1 -> stringResource(Res.string.you_and_1_other)
else -> "You and ${selectChatRoomTypeUIState.members.size} others"
},
style = MaterialTheme.typography.labelLarge
@@ -211,7 +219,7 @@ fun SelectChatRoomTypeScreen(
}
Text(
text = "This decides who can change the group later. You can't switch afterwards.",
text = stringResource(Res.string.this_decides_who_can_change_the_group_later),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth().padding(horizontal = MaterialTheme.spacing.space125)
@@ -400,7 +408,7 @@ private fun QuorumPicker(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space50)
) {
Text(
text = "How many admins have to approve a change?",
text = stringResource(Res.string.how_many_admins_have_to_approve_a_change),
style = MaterialTheme.typography.titleSmall
)
@@ -45,6 +45,12 @@ import press.mantra.compose.ui.view.state.ShareProfileUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.profile
import mantra.composeapp.generated.resources.re_broadcast
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.we_couldn_t_find_the_local_profile_please
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -73,7 +79,7 @@ fun ShareProfileScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Something went wrong")
Text(stringResource(Res.string.something_went_wrong))
}
}
is ShareProfileUIState.Loaded -> {
@@ -82,7 +88,7 @@ fun ShareProfileScreen(
TopAppBar(
title = {
Text(
text = "Profile"
text = stringResource(Res.string.profile)
)
},
navigationIcon = {
@@ -192,7 +198,7 @@ fun ShareProfileScreen(
}
) {
Text(
"Re-broadcast"
stringResource(Res.string.re_broadcast)
)
}
}
@@ -212,7 +218,7 @@ fun ShareProfileScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("We couldn't find the local profile. Please try again later.")
Text(stringResource(Res.string.we_couldn_t_find_the_local_profile_please))
}
}
}
@@ -32,6 +32,18 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.be_sure_to_keep_this_nsec_safe
import mantra.composeapp.generated.resources.enter_the_nsec_or_npub_read_only_that_you
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.nsec_npub_nip_05_static_address
import mantra.composeapp.generated.resources.sign_in
import mantra.composeapp.generated.resources.sign_in_to_nsec
import mantra.composeapp.generated.resources.sign_in_with_an_npub
import mantra.composeapp.generated.resources.something_went_wrong_and_we_were_unable_to
import mantra.composeapp.generated.resources.this_will_give_you_read_only_access_to_the
import mantra.composeapp.generated.resources.this_will_give_you_write_access_to_the
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -63,7 +75,7 @@ fun SignInToProfileScreen(
when (val signInToProfileUIState = signInToProfileViewModel.signInToProfileUIState.value) {
is press.mantra.compose.ui.view.state.SignInToProfileUIState.InputPrompt -> {
Text(
"Sign in",
stringResource(Res.string.sign_in),
style = MaterialTheme.typography.headlineSmall
)
@@ -87,13 +99,13 @@ fun SignInToProfileScreen(
),
label = {
Text(
text = "nsec, npub, nip-05 (static address)",
text = stringResource(Res.string.nsec_npub_nip_05_static_address),
maxLines = 1,
)
},
placeholder = {
Text(
text = "Enter the nsec or npub (read only) that you want to sign in as",
text = stringResource(Res.string.enter_the_nsec_or_npub_read_only_that_you),
maxLines = 1,
)
},
@@ -129,7 +141,7 @@ fun SignInToProfileScreen(
},
) {
Text(
"Next"
stringResource(Res.string.next)
)
Icon(
Icons.Default.NavigateNext,
@@ -144,7 +156,7 @@ fun SignInToProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Sign in with an npub",
text = stringResource(Res.string.sign_in_with_an_npub),
style = MaterialTheme.typography.headlineMedium
)
@@ -168,7 +180,7 @@ fun SignInToProfileScreen(
Text(
text = "This will give you read only access to the profile.",
text = stringResource(Res.string.this_will_give_you_read_only_access_to_the),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
@@ -184,7 +196,7 @@ fun SignInToProfileScreen(
}
) {
Text(
text = "Sign in"
text = stringResource(Res.string.sign_in)
)
}
}
@@ -196,12 +208,12 @@ fun SignInToProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Sign in to nsec",
text = stringResource(Res.string.sign_in_to_nsec),
style = MaterialTheme.typography.headlineMedium
)
Text(
text = "Be sure to keep this nsec safe.",
text = stringResource(Res.string.be_sure_to_keep_this_nsec_safe),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium
)
@@ -214,7 +226,7 @@ fun SignInToProfileScreen(
Text(
text = "This will give you write access to the profile.",
text = stringResource(Res.string.this_will_give_you_write_access_to_the),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
@@ -230,7 +242,7 @@ fun SignInToProfileScreen(
}
) {
Text(
text = "Sign in"
text = stringResource(Res.string.sign_in)
)
}
}
@@ -241,7 +253,7 @@ fun SignInToProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Something went wrong and we were unable to sign in to your provided profile. Please try again later.",
text = stringResource(Res.string.something_went_wrong_and_we_were_unable_to),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -23,6 +23,14 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.invite_a_friend
import mantra.composeapp.generated.resources.skip_for_now
import mantra.composeapp.generated.resources.tell_friends_to_join_you_so_your_feed_stays
import mantra.composeapp.generated.resources.view_and_accept_invites_you_may_have
import mantra.composeapp.generated.resources.view_invites
import mantra.composeapp.generated.resources.who_will_you_be_passing_the_aux_to
@Composable
fun SocialPreconditionScreen(
@@ -47,7 +55,7 @@ fun SocialPreconditionScreen(
)
},
text = {
Text("Skip for now")
Text(stringResource(Res.string.skip_for_now))
},
onClick = {
onNavigateToSkipForNow.invoke()
@@ -67,7 +75,7 @@ fun SocialPreconditionScreen(
) {
Text(
"Who will you be passing the aux to?",
stringResource(Res.string.who_will_you_be_passing_the_aux_to),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
@@ -77,7 +85,7 @@ fun SocialPreconditionScreen(
)
Text(
"Tell friends to join you so your feed stays lively and fresh.",
stringResource(Res.string.tell_friends_to_join_you_so_your_feed_stays),
textAlign = TextAlign.Center
)
@@ -87,7 +95,7 @@ fun SocialPreconditionScreen(
}
) {
Text(
"Invite a friend"
stringResource(Res.string.invite_a_friend)
)
}
@@ -96,7 +104,7 @@ fun SocialPreconditionScreen(
)
Text(
"View and accept invites you may have received to stay connected with others.",
stringResource(Res.string.view_and_accept_invites_you_may_have),
textAlign = TextAlign.Center
)
@@ -105,7 +113,7 @@ fun SocialPreconditionScreen(
onNavigateToViewInvites.invoke()
}
) {
Text("View invites")
Text(stringResource(Res.string.view_invites))
}
}
}
@@ -27,6 +27,11 @@ import fr.acinq.phoenix.utils.preferences.UserWalletMetadata
import fr.acinq.phoenix.utils.preferences.getByWalletIdOrDefault
import kotlinx.coroutines.flow.first
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.lock_prompt_coming_soon
import mantra.composeapp.generated.resources.select_a_wallet
import mantra.composeapp.generated.resources.startup_error
@Composable
fun SovereignWalletStartupScreen(
@@ -135,7 +140,7 @@ fun SovereignWalletStartupScreen(
topContent = {
Spacer(Modifier.height(MaterialTheme.spacing.space800))
Text(
text = "Select a wallet",
text = stringResource(Res.string.select_a_wallet),
style = MaterialTheme.typography.headlineSmall
)
Spacer(Modifier.height(MaterialTheme.spacing.space200))
@@ -191,7 +196,7 @@ fun SovereignWalletStartupScreen(
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = "Startup error"
text = stringResource(Res.string.startup_error)
)
when (startupState) {
@@ -280,7 +285,7 @@ private fun BoxScope.ScreenLockPrompt(
goToWalletSelector: (() -> Unit)?,
) {
Text(
text = "Lock prompt coming soon.",
text = stringResource(Res.string.lock_prompt_coming_soon),
)
// val scope = rememberCoroutineScope()
//
@@ -54,6 +54,14 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.TranslateChunkViewModel
import press.mantra.compose.ui.view.state.TranslateChunkUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.enter_the_translation_for_this_chunk
import mantra.composeapp.generated.resources.original
import mantra.composeapp.generated.resources.propose_translation
import mantra.composeapp.generated.resources.translate_chunk
import mantra.composeapp.generated.resources.translated_text
import mantra.composeapp.generated.resources.translation
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -109,7 +117,7 @@ fun TranslateChunkScreen(
modifier = Modifier.imePadding(),
topBar = {
TopAppBar(
title = { Text("Translate chunk") },
title = { Text(stringResource(Res.string.translate_chunk)) },
navigationIcon = {
IconButton(onClick = onNavigateBack) {
Icon(
@@ -177,7 +185,7 @@ fun TranslateChunkScreen(
Icons.Default.Add,
contentDescription = "Propose translation"
)
Text("Propose translation")
Text(stringResource(Res.string.propose_translation))
}
}
)
@@ -201,7 +209,7 @@ fun TranslateChunkScreen(
}
Text(
text = "Original",
text = stringResource(Res.string.original),
style = MaterialTheme.typography.labelMedium
)
Card {
@@ -213,14 +221,14 @@ fun TranslateChunkScreen(
}
Text(
text = "Translation",
text = stringResource(Res.string.translation),
style = MaterialTheme.typography.labelMedium
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
state = translationFieldState,
label = { Text("Translated text") },
placeholder = { Text("Enter the translation for this chunk") },
label = { Text(stringResource(Res.string.translated_text)) },
placeholder = { Text(stringResource(Res.string.enter_the_translation_for_this_chunk)) },
)
}
}
@@ -234,7 +242,7 @@ fun TranslateChunkScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Translate chunk",
text = stringResource(Res.string.translate_chunk),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -47,6 +47,14 @@ import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.TranslationArtifactVersionDetailViewModel
import press.mantra.compose.ui.view.state.TranslationArtifactVersionDetailUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.chapters
import mantra.composeapp.generated.resources.details
import mantra.composeapp.generated.resources.no_chapters
import mantra.composeapp.generated.resources.propose
import mantra.composeapp.generated.resources.this_group_has_no_shared_key_so_it_cannot
import mantra.composeapp.generated.resources.translation_detail
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -134,7 +142,7 @@ fun TranslationArtifactVersionDetailScreen(
supportingContent = {
Text(
if (!translationDetailUIState.canSign) {
"This group has no shared key, so it cannot sign them in."
stringResource(Res.string.this_group_has_no_shared_key_so_it_cannot)
} else {
"They were signed into the artifact after this " +
"translation. Ask the group to add them so they " +
@@ -166,7 +174,7 @@ fun TranslationArtifactVersionDetailScreen(
)
}
) {
Text("Propose")
Text(stringResource(Res.string.propose))
}
}
)
@@ -179,12 +187,12 @@ fun TranslationArtifactVersionDetailScreen(
// Chapters with translation progress
item {
Text(
text = "Chapters",
text = stringResource(Res.string.chapters),
style = MaterialTheme.typography.labelMedium
)
}
if (translationDetailUIState.chapters.isEmpty()) {
item { Text("No chapters.") }
item { Text(stringResource(Res.string.no_chapters)) }
} else {
items(
items = translationDetailUIState.chapters,
@@ -223,7 +231,7 @@ fun TranslationArtifactVersionDetailScreen(
// Details
item {
Text(
text = "Details",
text = stringResource(Res.string.details),
style = MaterialTheme.typography.labelMedium
)
}
@@ -250,7 +258,7 @@ fun TranslationArtifactVersionDetailScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Translation detail",
text = stringResource(Res.string.translation_detail),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -48,6 +48,10 @@ import press.mantra.compose.ui.view.model.TranslationChapterViewModel
import press.mantra.compose.ui.view.state.ChunkTranslationPair
import press.mantra.compose.ui.view.state.TranslationChapterUIState
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.chapter_translation
import mantra.composeapp.generated.resources.this_chapter_has_no_chunks
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -87,7 +91,7 @@ fun TranslationChapterScreen(
Scaffold(
topBar = {
TopAppBar(
title = { Text("Chapter translation") },
title = { Text(stringResource(Res.string.chapter_translation)) },
navigationIcon = {
IconButton(onClick = onNavigateBack) {
Icon(
@@ -127,7 +131,7 @@ fun TranslationChapterScreen(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.containerPadding),
contentAlignment = Alignment.Center
) {
Text("This chapter has no chunks.")
Text(stringResource(Res.string.this_chapter_has_no_chunks))
}
}
} else {
@@ -164,7 +168,7 @@ fun TranslationChapterScreen(
) {
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Chapter translation",
text = stringResource(Res.string.chapter_translation),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -18,6 +18,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.everything_is_cryptographical_sound_just
import mantra.composeapp.generated.resources.torch_will_be_broadcast_what_you_publish_to
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -39,13 +43,13 @@ fun UnannouncedProfileScreen() {
modifier = Modifier.weight(1f)
)
Text(
text = "Everything is cryptographical sound. Just announcing your profile to the world.",
text = stringResource(Res.string.everything_is_cryptographical_sound_just),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Torch will be broadcast what you publish to a distributed set of relays so that it's decentralized.",
text = stringResource(Res.string.torch_will_be_broadcast_what_you_publish_to),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -18,6 +18,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.events_are_indexed_so_that_we_can_deliver_a
import mantra.composeapp.generated.resources.everything_is_cryptographical_sound_just_2
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -39,13 +43,13 @@ fun UnindexedProfileScreen() {
modifier = Modifier.weight(1f)
)
Text(
text = "Everything is cryptographical sound. Just indexing your profile on the device.",
text = stringResource(Res.string.everything_is_cryptographical_sound_just_2),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "Events are indexed so that we can deliver a premium local first experience.",
text = stringResource(Res.string.events_are_indexed_so_that_we_can_deliver_a),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -18,6 +18,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.all_broadcasts_are_queued_so_that_we_can
import mantra.composeapp.generated.resources.everything_is_cryptographical_sound_just_3
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -39,13 +43,13 @@ fun UnqueuedProfileScreen() {
modifier = Modifier.weight(1f)
)
Text(
text = "Everything is cryptographical sound. Just need to queue your profile and announce it to the world.",
text = stringResource(Res.string.everything_is_cryptographical_sound_just_3),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "All broadcasts are queued so that we can manage data usage on metered connections.",
text = stringResource(Res.string.all_broadcasts_are_queued_so_that_we_can),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -20,6 +20,10 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.we_are_looking_for_your_profile_on_as_many
import mantra.composeapp.generated.resources.we_are_searching_the_internet_to_find_your
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -53,13 +57,13 @@ fun UnqueuedProfileSynchronizationScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "We are searching the internet to find your profile and complete sign in.",
text = stringResource(Res.string.we_are_searching_the_internet_to_find_your),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "We are looking for your profile on as many relays as possible. Nostr aims to be decentralized by distributing data to multiple nodse.",
text = stringResource(Res.string.we_are_looking_for_your_profile_on_as_many),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -18,6 +18,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.as_long_as_you_control_your_keys_there_can
import mantra.composeapp.generated.resources.your_profile_is_almost_ready_just_getting_it
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -39,13 +43,13 @@ fun UnsignedProfileScreen() {
modifier = Modifier.weight(1f)
)
Text(
text = "Your profile is almost ready... just getting it's first cryptographic signature together.",
text = stringResource(Res.string.your_profile_is_almost_ready_just_getting_it),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "As long as you control your keys there can be no dispute about who YOU actually is.",
text = stringResource(Res.string.as_long_as_you_control_your_keys_there_can),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -18,6 +18,10 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.we_are_looking_for_your_profile_on_as_many
import mantra.composeapp.generated.resources.we_are_searching_the_internet_to_find_your
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -41,13 +45,13 @@ fun UnsyncedProfileScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "We are searching the internet to find your profile and complete sign in.",
text = stringResource(Res.string.we_are_searching_the_internet_to_find_your),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
Text(
text = "We are looking for your profile on as many relays as possible. Nostr aims to be decentralized by distributing data to multiple nodse.",
text = stringResource(Res.string.we_are_looking_for_your_profile_on_as_many),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center
)
@@ -45,6 +45,16 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import kotlin.time.Clock
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.something_went_wrong_and_we_were_unable_to_3
import mantra.composeapp.generated.resources.the_above_will_be_your_new_note
import mantra.composeapp.generated.resources.transmit_note
import mantra.composeapp.generated.resources.type_out_what_you_would_like_to_publish
import mantra.composeapp.generated.resources.what_s_your_comment_on_the_below
import mantra.composeapp.generated.resources.what_s_your_reply_to_the_above
import mantra.composeapp.generated.resources.what_vibrations_do_you_want_to_send_out
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalFoundationApi::class)
@Composable
@@ -148,18 +158,18 @@ fun WriteNewNoteScreen(
label = {
Text(
text = if (writeNewNoteUIState.inReplyToNostrEvent != null) {
"What's your reply to the above"
stringResource(Res.string.what_s_your_reply_to_the_above)
} else if (writeNewNoteUIState.quotedNostrEvent != null) {
"What's your comment on the below"
stringResource(Res.string.what_s_your_comment_on_the_below)
} else {
"What vibrations do you want to send out?"
stringResource(Res.string.what_vibrations_do_you_want_to_send_out)
},
maxLines = 1,
)
},
placeholder = {
Text(
text = "Type out what you would like to publish",
text = stringResource(Res.string.type_out_what_you_would_like_to_publish),
maxLines = 1,
)
},
@@ -271,7 +281,7 @@ fun WriteNewNoteScreen(
},
) {
Text(
"Next"
stringResource(Res.string.next)
)
Icon(
Icons.Default.NavigateNext,
@@ -399,7 +409,7 @@ fun WriteNewNoteScreen(
}
Text(
text = "The above will be your new note.",
text = stringResource(Res.string.the_above_will_be_your_new_note),
style = MaterialTheme.typography.bodySmall
)
@@ -419,7 +429,7 @@ fun WriteNewNoteScreen(
}
) {
Text(
text = "Transmit note"
text = stringResource(Res.string.transmit_note)
)
}
}
@@ -430,7 +440,7 @@ fun WriteNewNoteScreen(
modifier = Modifier.weight(1f)
)
Text(
text = "Something went wrong and we were unable to write a new note. Please try again later.",
text = stringResource(Res.string.something_went_wrong_and_we_were_unable_to_3),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
)
@@ -22,6 +22,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.article
import mantra.composeapp.generated.resources.loading_article
import mantra.composeapp.generated.resources.untitled_article
@Composable
private fun ArticleCard(
@@ -71,7 +76,7 @@ private fun ArticleCard(
)
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading article...",
text = stringResource(Res.string.loading_article),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -99,14 +104,14 @@ private fun ArticleCard(
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "ARTICLE",
text = stringResource(Res.string.article),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
)
}
Text(
text = title ?: "Untitled article",
text = title ?: stringResource(Res.string.untitled_article),
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface,
maxLines = 2,
@@ -33,6 +33,11 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.copy_url
import mantra.composeapp.generated.resources.download
import mantra.composeapp.generated.resources.tap_to_load
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -67,7 +72,7 @@ internal fun ImageWithContextMenu(meta: MediaMeta, onFullScreen: () -> Unit) {
)
Spacer(Modifier.height(MaterialTheme.spacing.space100))
Text(
"Tap to load",
stringResource(Res.string.tap_to_load),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -95,14 +100,14 @@ internal fun ImageWithContextMenu(meta: MediaMeta, onFullScreen: () -> Unit) {
onDismissRequest = { showMenu = false }
) {
DropdownMenuItem(
text = { Text("Copy URL") },
text = { Text(stringResource(Res.string.copy_url)) },
onClick = {
clipboardManager.setText(AnnotatedString(url))
showMenu = false
}
)
DropdownMenuItem(
text = { Text("Download") },
text = { Text(stringResource(Res.string.download)) },
onClick = {
showMenu = false
// scope.launch { MediaDownloader.downloadMedia(context, url) }
@@ -35,6 +35,16 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.any_amount
import mantra.composeapp.generated.resources.cancel
import mantra.composeapp.generated.resources.expired
import mantra.composeapp.generated.resources.failed
import mantra.composeapp.generated.resources.lightning_invoice
import mantra.composeapp.generated.resources.paid
import mantra.composeapp.generated.resources.pay
import mantra.composeapp.generated.resources.pay_now
@Composable
internal fun LightningInvoiceCard(
@@ -52,7 +62,7 @@ internal fun LightningInvoiceCard(
if (showConfirm) {
AlertDialog(
onDismissRequest = { showConfirm = false },
title = { Text("Lightning invoice") },
title = { Text(stringResource(Res.string.lightning_invoice)) },
text = {
Column {
Text(
@@ -86,11 +96,11 @@ internal fun LightningInvoiceCard(
containerColor = primary,
contentColor = onPrimary
)
) { Text("Pay") }
) { Text(stringResource(Res.string.pay)) }
},
dismissButton = {
TextButton(onClick = { showConfirm = false }) {
Text("Cancel")
Text(stringResource(Res.string.cancel))
}
}
)
@@ -119,7 +129,7 @@ internal fun LightningInvoiceCard(
Text(
text = if (decoded.amount != null)
"${decoded.amount!!.truncateToSatoshi()}"
else "Any amount",
else stringResource(Res.string.any_amount),
style = MaterialTheme.typography.titleSmall,
color = primary
)
@@ -133,7 +143,7 @@ internal fun LightningInvoiceCard(
}
if (isExpired) {
Text(
text = "Expired",
text = stringResource(Res.string.expired),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.error
)
@@ -148,12 +158,12 @@ internal fun LightningInvoiceCard(
strokeWidth = 2.dp
)
InvoicePayState.Success -> Text(
text = "✓ Paid",
text = stringResource(Res.string.paid),
style = MaterialTheme.typography.labelMedium,
color = primary
)
InvoicePayState.Failed -> Text(
text = "✗ Failed",
text = stringResource(Res.string.failed),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.error
)
@@ -166,8 +176,8 @@ internal fun LightningInvoiceCard(
)
) {
Text(
if (isExpired) "Expired"
else "Pay now"
if (isExpired) stringResource(Res.string.expired)
else stringResource(Res.string.pay_now)
)
}
}
@@ -20,6 +20,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.ended
import mantra.composeapp.generated.resources.live
import mantra.composeapp.generated.resources.live_stream
import mantra.composeapp.generated.resources.loading_stream
@Composable
internal fun LiveStreamCardContent(
@@ -45,7 +51,7 @@ internal fun LiveStreamCardContent(
)
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading stream...",
text = stringResource(Res.string.loading_stream),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -92,7 +98,7 @@ internal fun LiveStreamCardContent(
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "LIVE",
text = stringResource(Res.string.live),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onError,
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
@@ -105,7 +111,7 @@ internal fun LiveStreamCardContent(
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "ENDED",
text = stringResource(Res.string.ended),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
@@ -113,7 +119,7 @@ internal fun LiveStreamCardContent(
}
}
Text(
text = title ?: "Live stream",
text = title ?: stringResource(Res.string.live_stream),
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface,
maxLines = 2,
@@ -18,6 +18,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading_note
@Composable
@@ -64,7 +67,7 @@ internal fun QuotedAddressableNote(
)
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading note...",
text = stringResource(Res.string.loading_note),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -21,6 +21,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading_note
@Composable
fun QuotedNote(
@@ -105,7 +108,7 @@ fun QuotedNote(
)
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading note...",
text = stringResource(Res.string.loading_note),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -12,6 +12,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.unsupported_event_kind
@Composable
internal fun UnsupportedKindBadge(kind: Int?, style: TextStyle) {
@@ -24,7 +27,7 @@ internal fun UnsupportedKindBadge(kind: Int?, style: TextStyle) {
.padding(vertical = MaterialTheme.spacing.space75)
) {
Text(
text = if (kind != null) "Unsupported event kind: $kind" else "Unsupported event kind",
text = if (kind != null) "Unsupported event kind: $kind" else stringResource(Res.string.unsupported_event_kind),
style = style,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(MaterialTheme.spacing.space175)
@@ -58,6 +58,15 @@ import press.mantra.compose.ui.view.state.MetadataEventDetailUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.add_to_group
import mantra.composeapp.generated.resources.block_user
import mantra.composeapp.generated.resources.edit_profile
import mantra.composeapp.generated.resources.follow
import mantra.composeapp.generated.resources.follow_back
import mantra.composeapp.generated.resources.send_message
import mantra.composeapp.generated.resources.unfollow
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -181,7 +190,7 @@ fun MetadataEventDetail(
onClick = onNavigateToEditProfile
) {
Text(
"Edit profile"
stringResource(Res.string.edit_profile)
)
}
@@ -195,7 +204,7 @@ fun MetadataEventDetail(
}
) {
Text(
"Unfollow"
stringResource(Res.string.unfollow)
)
}
} else {
@@ -207,9 +216,9 @@ fun MetadataEventDetail(
) {
Text(
text = if (metadataEventDetailUIState.followingActiveUserConnection != null) {
"follow back"
stringResource(Res.string.follow_back)
} else {
"follow"
stringResource(Res.string.follow)
}
)
}
@@ -252,7 +261,7 @@ fun MetadataEventDetail(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add to group")
Text(stringResource(Res.string.add_to_group))
}
}
@@ -273,7 +282,7 @@ fun MetadataEventDetail(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Block user")
Text(stringResource(Res.string.block_user))
}
}
@@ -297,7 +306,7 @@ fun MetadataEventDetail(
Spacer(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Send message")
Text(stringResource(Res.string.send_message))
}
}
}
@@ -49,6 +49,11 @@ import press.mantra.compose.extensions.toFormattedTimeAndDateString
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.be_the_first_to_comment
import mantra.composeapp.generated.resources.post
import mantra.composeapp.generated.resources.something_went_wrong
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -87,7 +92,7 @@ fun TextNoteEventDetail(
}
},
title = {
Text("Post")
Text(stringResource(Res.string.post))
},
)
},
@@ -346,7 +351,7 @@ fun TextNoteEventDetail(
if (inReplyToFeedListUIState.localNostrEvents.isEmpty()) {
item {
Text(
"Be the first to comment."
stringResource(Res.string.be_the_first_to_comment)
)
}
} else {
@@ -363,7 +368,7 @@ fun TextNoteEventDetail(
press.mantra.compose.ui.view.state.FeedListUIState.Error -> {
item {
Text(
text = "Something went wrong"
text = stringResource(Res.string.something_went_wrong)
)
}
}
@@ -29,6 +29,12 @@ import press.mantra.compose.ui.composable.navigation.routes.Route
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.close
import mantra.composeapp.generated.resources.create_new_chat
import mantra.composeapp.generated.resources.direct_message_via_npub
import mantra.composeapp.generated.resources.start_a_group_chat
@OptIn(ExperimentalMaterial3Api::class)
@@ -55,7 +61,7 @@ fun NewChatBottomSheetDialog(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Create new chat",
text = stringResource(Res.string.create_new_chat),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyLarge
)
@@ -74,7 +80,7 @@ fun NewChatBottomSheetDialog(
)
},
headlineContent = {
Text("Direct message via npub")
Text(stringResource(Res.string.direct_message_via_npub))
},
trailingContent = {
Icon(
@@ -101,7 +107,7 @@ fun NewChatBottomSheetDialog(
},
headlineContent = {
Text(
text = "Start a group chat"
text = stringResource(Res.string.start_a_group_chat)
)
},
trailingContent = {
@@ -129,7 +135,7 @@ fun NewChatBottomSheetDialog(
Spacer(
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Close")
Text(stringResource(Res.string.close))
}
}
@@ -46,6 +46,11 @@ import press.mantra.compose.ui.theme.spacing
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.input_npub_or_nip05
import mantra.composeapp.generated.resources.start_chat
import mantra.composeapp.generated.resources.start_chat_via_npub_or_nip05
@Composable
fun StartDirectMessageToNpubOrNip05Dialog(
@@ -91,7 +96,7 @@ fun StartDirectMessageToNpubOrNip05Dialog(
modifier = Modifier.fillMaxWidth().padding(
horizontal = MaterialTheme.spacing.space250,
),
text = "Start chat via npub or nip05",
text = stringResource(Res.string.start_chat_via_npub_or_nip05),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center
)
@@ -99,7 +104,7 @@ fun StartDirectMessageToNpubOrNip05Dialog(
modifier = Modifier.focusRequester(npubFieldFocus),
state = textFieldState,
placeholder = {
Text("Input npub... or nip05")
Text(stringResource(Res.string.input_npub_or_nip05))
},
trailingIcon = {
IconButton(
@@ -166,7 +171,7 @@ fun StartDirectMessageToNpubOrNip05Dialog(
}
}
) {
Text("Start chat")
Text(stringResource(Res.string.start_chat))
Spacer(
modifier = Modifier.width(MaterialTheme.spacing.space125)
@@ -25,6 +25,11 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import kotlin.time.Instant
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading_author_information_2
import mantra.composeapp.generated.resources.malformed_note
import mantra.composeapp.generated.resources.reposted
@Composable
fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
@@ -66,7 +71,7 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
color = press.mantra.compose.ui.composable.widgets.profile.ProfileColor.fromPublicKey(profile?.publicKey ?: nostrEvent.pubKey)
)
Text(
text = "reposted",
text = stringResource(Res.string.reposted),
style = MaterialTheme.typography.labelSmall
)
}
@@ -92,7 +97,7 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
).containedPost()
if (containedPost != null) {
Text("Loading author information...")
Text(stringResource(Res.string.loading_author_information_2))
Text(
containedPost.content
)
@@ -100,7 +105,7 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
text = Instant.fromEpochSeconds(containedPost.createdAt).toFormattedTimeAndDateString()
)
} else {
Text("Malformed note")
Text(stringResource(Res.string.malformed_note))
}
}
@@ -26,6 +26,10 @@ import androidx.compose.ui.unit.dp
import press.mantra.compose.extensions.toFormattedTimeAndDateString
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading_author_information
import mantra.composeapp.generated.resources.loading_information
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -63,7 +67,7 @@ internal fun TextNoteFeedItem(
),
style = MaterialTheme.typography.labelLargeEmphasized,
color = press.mantra.compose.ui.composable.widgets.profile.ProfileColor.fromPublicKey(localInReplyToNostrEvent.nostrEvent.pubKey),
text = localInReplyToNostrEvent.profile?.humanReadableNameOrPubkey() ?: "loading information..."
text = localInReplyToNostrEvent.profile?.humanReadableNameOrPubkey() ?: stringResource(Res.string.loading_information)
)
}
}
@@ -116,7 +120,7 @@ internal fun TextNoteFeedItem(
}
} else {
Text(
text = "Loading author information"
text = stringResource(Res.string.loading_author_information)
)
}
@@ -94,6 +94,16 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import press.mantra.compose.ui.composable.widgets.Decorative
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.currently_no_messages_have_been_shared
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_chat_message_relays_were_found_for_this
import mantra.composeapp.generated.resources.private_to_you
import mantra.composeapp.generated.resources.review
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.waiting_for_your_signature
import mantra.composeapp.generated.resources.you
class ChatMessageListViewModel(
initialChatMessageListUIState: ChatMessageListUIState,
@@ -399,7 +409,7 @@ class ChatMessageListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -420,7 +430,7 @@ class ChatMessageListViewModel(
)
Text(
modifier = Modifier.padding(MaterialTheme.spacing.space250),
text = "Currently no messages have been shared.\nBreak the ice.",
text = stringResource(Res.string.currently_no_messages_have_been_shared),
textAlign = TextAlign.Center
)
@@ -489,7 +499,7 @@ class ChatMessageListViewModel(
modifier = Modifier.weight(1f)
) {
Text(
text = "No chat message relays were found for this user.",
text = stringResource(Res.string.no_chat_message_relays_were_found_for_this),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.labelSmall
)
@@ -660,7 +670,7 @@ class ChatMessageListViewModel(
text = if (localChatMessage.chatMessage.isUserMessage) {
"Private to ${nameFor(localChatMessage.chatMessage.directMessageRecipientPublicKey)}"
} else {
"Private to you"
stringResource(Res.string.private_to_you)
},
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.labelSmall
@@ -750,7 +760,7 @@ class ChatMessageListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(
@@ -875,7 +885,7 @@ private fun ProposalsAwaitingYouNotice(
) {
Text(
text = if (single != null) {
"Waiting for your signature"
stringResource(Res.string.waiting_for_your_signature)
} else {
"${proposals.size} proposals are waiting for your signature"
},
@@ -896,7 +906,7 @@ private fun ProposalsAwaitingYouNotice(
// thing, so a member reading down the room is not asked twice in two
// vocabularies.
Text(
text = "Review",
text = stringResource(Res.string.review),
style = MaterialTheme.typography.labelLarge
)
@@ -1062,7 +1072,7 @@ private fun RitualNotice(
) {
append(
if (chatMessage.isUserMessage) {
"You"
stringResource(Res.string.you)
} else {
localChatMessage.profile?.humanReadableNameOrPubkey()
?: chatMessage.senderPublicKey.shortened()
@@ -1087,7 +1097,7 @@ private fun RitualNotice(
if (isRequest) {
Text(
text = "Review",
text = stringResource(Res.string.review),
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.primary
)
@@ -41,6 +41,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_messages_go_to_a_profile_and_send_them_a
import mantra.composeapp.generated.resources.something_went_wrong
class ChatRoomListViewModel(
initialChatRoomListUIState: ChatRoomListUIState,
@@ -154,7 +159,7 @@ class ChatRoomListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -167,7 +172,7 @@ class ChatRoomListViewModel(
if (chatRoomListUIState.chatRoomList.isEmpty()) {
Text(
text = "No messages. Go to a profile and send them a message."
text = stringResource(Res.string.no_messages_go_to_a_profile_and_send_them_a)
)
} else {
LazyColumn(
@@ -236,7 +241,7 @@ class ChatRoomListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(
@@ -35,6 +35,11 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_events_were_found
import mantra.composeapp.generated.resources.something_went_wrong
class FeedListViewModel(
initialFeedListUIState: FeedListUIState,
@@ -121,7 +126,7 @@ class FeedListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -135,7 +140,7 @@ class FeedListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "No events were found",
text = stringResource(Res.string.no_events_were_found),
)
}
} else {
@@ -172,7 +177,7 @@ class FeedListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(
@@ -31,6 +31,11 @@ import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_events_were_found
import mantra.composeapp.generated.resources.something_went_wrong
class FollowersListViewModel(
initialFollowingListUIState: press.mantra.compose.ui.view.state.FollowersListUIState,
@@ -115,7 +120,7 @@ class FollowersListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -129,7 +134,7 @@ class FollowersListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "No events were found",
text = stringResource(Res.string.no_events_were_found),
)
}
} else {
@@ -160,7 +165,7 @@ class FollowersListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(
@@ -31,6 +31,11 @@ import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_events_were_found
import mantra.composeapp.generated.resources.something_went_wrong
class FollowingListViewModel(
initialFollowingListUIState: press.mantra.compose.ui.view.state.FollowingListUIState,
@@ -114,7 +119,7 @@ class FollowingListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -128,7 +133,7 @@ class FollowingListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "No events were found",
text = stringResource(Res.string.no_events_were_found),
)
}
} else {
@@ -159,7 +164,7 @@ class FollowingListViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(
@@ -36,6 +36,11 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlin.time.Instant
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.loading
import mantra.composeapp.generated.resources.no_events_were_found
import mantra.composeapp.generated.resources.something_went_wrong
class InReplyToViewModel(
val nostrEvent: press.mantra.compose.database.model.NostrEvent,
@@ -125,7 +130,7 @@ class InReplyToViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Something went wrong",
text = stringResource(Res.string.something_went_wrong),
)
}
}
@@ -139,7 +144,7 @@ class InReplyToViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "No events were found",
text = stringResource(Res.string.no_events_were_found),
)
}
} else {
@@ -176,7 +181,7 @@ class InReplyToViewModel(
modifier = Modifier.height(MaterialTheme.spacing.space600)
)
Text(
text = "Loading",
text = stringResource(Res.string.loading),
textAlign = TextAlign.Center
)
Spacer(