From 98d653a8f8da8a85614bb223c1b514428803bf91 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Wed, 16 Mar 2022 14:40:33 +0800 Subject: [PATCH] Membership: i18n fixes + add strings - Variable names are for translators to determine the context, so choose more relevant names. e.g 'displayedInterval' and 'date_range' will not make much sense to a non-programmer. - No need to localize dev-only strings. - Various other fixes. --- static/app-strings.json | 63 +++++++++- ui/component/common/premium-badge.jsx | 10 +- ui/component/membershipSplash/view.jsx | 16 ++- .../modalConfirmOdyseeMembership/view.jsx | 2 +- ui/page/odyseeMembership/view.jsx | 115 +++++++----------- 5 files changed, 122 insertions(+), 84 deletions(-) diff --git a/static/app-strings.json b/static/app-strings.json index e3c7f9c93..004aa1d15 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -970,8 +970,7 @@ "Trending For Your Tags": "Trending For Your Tags", "Latest From @lbry": "Latest From @lbry", "Latest From @lbrycast": "Latest From @lbrycast", - "Hate these? %log_in_to_domain% for an ad free experience.": "Hate these? %log_in_to_domain% for an ad free experience.", - "Hate these? Login to Odysee for an ad free experience": "Hate these? Login to Odysee for an ad free experience", + "Hate these? %sign_up_for_premium% for an ad free experience.": "Hate these? %sign_up_for_premium% for an ad free experience.", "Log in to %domain%": "Log in to %domain%", "odysee collects usage information for itself only (%more_information%).": "odysee collects usage information for itself only (%more_information%).", "odysee collects usage information for itself only (%more_information%). Want control over this and more?": "odysee collects usage information for itself only (%more_information%). Want control over this and more?", @@ -2205,5 +2204,65 @@ "Recently Active": "Recently Active", "All Channels": "All Channels", "# Recommended Videos - Alpha version available to Odysee Premium users\n ## What is this?\n Our content catalog is growing fast. Each day, there are more creators using the platform. This is great news! But it also makes finding things you would like to watch harder. Odysee's recommended videos tries to make it easier.\n\n ## How does it work?\n Based on your video viewing history, Odysee tries to find other channels you might like. Then, we recommend videos from those channels. At least, that's how it works right now. But expect a lot of rapid change.\n\n ## Does Odysee manipulate the results?\n No. The current algorithm itself has a tendency to favor channels with more viewers. But this is just because we have more evidence for those ones. Otherwise, we aren't making editorial decisions or picking favorites.\n\n ## My results suck, wtf?\n The more videos you watch, the better it should be. But this system is brand new and it will take a bit of time to tune it. Please have patience. Or, if you want to complain or suggest something, please email: mailto:recommendations@odysee.com\n\n ## Why don't I have any recommendations?\n Right now, it's a Premium feature. But you also might not be using Odysee enough. It's hard to make recommendations without knowing much about you. Otherwise, if you use uBlock Origin or Brave, make sure they are disabled on Odysee, as they interfere with us learning what you like.": "# Recommended Videos - Alpha version available to Odysee Premium users\n ## What is this?\n Our content catalog is growing fast. Each day, there are more creators using the platform. This is great news! But it also makes finding things you would like to watch harder. Odysee's recommended videos tries to make it easier.\n\n ## How does it work?\n Based on your video viewing history, Odysee tries to find other channels you might like. Then, we recommend videos from those channels. At least, that's how it works right now. But expect a lot of rapid change.\n\n ## Does Odysee manipulate the results?\n No. The current algorithm itself has a tendency to favor channels with more viewers. But this is just because we have more evidence for those ones. Otherwise, we aren't making editorial decisions or picking favorites.\n\n ## My results suck, wtf?\n The more videos you watch, the better it should be. But this system is brand new and it will take a bit of time to tune it. Please have patience. Or, if you want to complain or suggest something, please email: mailto:recommendations@odysee.com\n\n ## Why don't I have any recommendations?\n Right now, it's a Premium feature. But you also might not be using Odysee enough. It's hard to make recommendations without knowing much about you. Otherwise, if you use uBlock Origin or Brave, make sure they are disabled on Odysee, as they interfere with us learning what you like.", + "Odysee Premium": "Odysee Premium", + "Get Odysee Premium+": "Get Odysee Premium+", + "Expand to learn more about how Odysee Premium works": "Expand to learn more about how Odysee Premium works", + "Get More Information": "Get More Information", + "First of all, thank you for considering or purchasing a membership, it means a ton to us! A few important details to know:": "First of all, thank you for considering or purchasing a membership, it means a ton to us! A few important details to know:", + "Exclusive and early access features include: recommended content on homepage, livestreaming, and the ability to post odysee hyperlinks + images in comments. Account is also automatically eligible for Rewards. More to come later.": "Exclusive and early access features include: recommended content on homepage, livestreaming, and the ability to post odysee hyperlinks + images in comments. Account is also automatically eligible for Rewards. More to come later.", + "The yearly Premium+ membership has a discount compared to monthly, and Premium is only available yearly.": "The yearly Premium+ membership has a discount compared to monthly, and Premium is only available yearly.", + "These are limited time rates, so get in early!": "These are limited time rates, so get in early!", + "There may be higher tiers available in the future for creators and anyone else who wants to support us.": "There may be higher tiers available in the future for creators and anyone else who wants to support us.", + "Badges will be displayed on a single channel to start, with an option to add on two more later on.": "Badges will be displayed on a single channel to start, with an option to add on two more later on.", + "Cannot upgrade or downgrade a membership at this time. Refunds are not available. Choose wisely.": "Cannot upgrade or downgrade a membership at this time. Refunds are not available. Choose wisely.", + "Creating a revolutionary video platform for everyone is something we're proud to be doing, but it isn't something that can happen without support. If you believe in Odysee's mission, please consider becoming a Premium member. As a Premium member, you'll be helping us build the best platform in the universe and we'll give you some cool perks!": "Creating a revolutionary video platform for everyone is something we're proud to be doing, but it isn't something that can happen without support. If you believe in Odysee's mission, please consider becoming a Premium member. As a Premium member, you'll be helping us build the best platform in the universe and we'll give you some cool perks!", + "Exclusive and early access to features": "Exclusive and early access to features", + "Badge on profile": "Badge on profile", + "All Premium features, and no ads": "All Premium features, and no ads", + "No ads": "No ads", + "%premium_price% %premium_recurrence% --[context: '99¢ A MONTH']--": "%premium_price% %premium_recurrence%", + "A MONTH": "A MONTH", + "Get %early_access% features and a %site_wide_badge%": "Get %early_access% features and a %site_wide_badge%", + "early access": "early access", + "site-wide badge": "site-wide badge", + "Available Memberships": "Available Memberships", + "Premium": "Premium", + "Badge on profile, livestreaming, automatic rewards confirmation, and early access to new features": "Badge on profile, livestreaming, automatic rewards confirmation, and early access to new features", + "Premium+": "Premium+", + "Badge on profile, livestreaming, automatic rewards confirmation, early access to new features, and no ads": "Badge on profile, livestreaming, automatic rewards confirmation, early access to new features, and no ads", + "Join via %interval% membership": "Join via %interval% membership", + "Interval": "Interval", + "Your Active Memberships": "Your Active Memberships", + "You currently have no active memberships": "You currently have no active memberships", + "Canceled Memberships": "Canceled Memberships", + "You currently have no canceled memberships": "You currently have no canceled memberships", + "You are purchasing a %monthly_yearly% %plan% membership that is active immediately and will renew %monthly_yearly% at a price of %price%.": "You are purchasing a %monthly_yearly% %plan% membership that is active immediately and will renew %monthly_yearly% at a price of %price%.", + "monthly": "monthly", + "yearly": "yearly", + "You can cancel Premium at any time (no refunds) and you can also close this window and choose a different membership option.": "You can cancel Premium at any time (no refunds) and you can also close this window and choose a different membership option.", + "Confirm %plan% Membership": "Confirm %plan% Membership", + "The no ads feature applies site-wide for all channels and your badge will be shown for your %channel_name% channel in all areas of the app, and can be added to two additional channels in the future for free.": "The no ads feature applies site-wide for all channels and your badge will be shown for your %channel_name% channel in all areas of the app, and can be added to two additional channels in the future for free.", + "The no ads feature applies site-wide. You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.": "The no ads feature applies site-wide. You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.", + "The no ads feature applies site-wide. You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.": "The no ads feature applies site-wide. You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.", + "Your badge will be shown for your %channel_name% channel in all areas of the app, and can be added to two additional channels in the future for free.": "Your badge will be shown for your %channel_name% channel in all areas of the app, and can be added to two additional channels in the future for free.", + "You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.": "You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.", + "You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.": "You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.", + "Completing your purchase...": "Completing your purchase...", + "Membership was successful": "Membership was successful", + "Sorry, your purchase wasn't able to completed. Please contact support for possible next steps": "Sorry, your purchase wasn't able to completed. Please contact support for possible next steps", + "Canceling your membership...": "Canceling your membership...", + "Membership successfully canceled": "Membership successfully canceled", + "Confirm Membership Cancellation": "Confirm Membership Cancellation", + "Confirm Cancellation": "Confirm Cancellation", + "You are cancelling your Odysee Premium. You will still have access to all the paid features until the point of the expiration of your current membership, at which point you will not be charged again and your membership will no longer be active. At this time, there is no way to subscribe to another membership if you cancel and there are no refunds.": "You are cancelling your Odysee Premium. You will still have access to all the paid features until the point of the expiration of your current membership, at which point you will not be charged again and your membership will no longer be active. At this time, there is no way to subscribe to another membership if you cancel and there are no refunds.", + "Sorry, there was an error, please contact support or try again later": "Sorry, there was an error, please contact support or try again later", + "Please save a card as a payment method so you can join Odysee Premium": "Please save a card as a payment method so you can join Odysee Premium", + "After the card is added, click Back": "After the card is added, click Back", + "Registered On": "Registered On", + "Auto-Renews On": "Auto-Renews On", + "Canceled On": "Canceled On", + "Still Valid Until": "Still Valid Until", + "Membership Period Options": "Membership Period Options", + "%yearly_cost% USD For A One Year Membership (%monthly_cost% Per Month)": "%yearly_cost% USD For A One Year Membership (%monthly_cost% Per Month)", "--end--": "--end--" } diff --git a/ui/component/common/premium-badge.jsx b/ui/component/common/premium-badge.jsx index f50f44679..54838452d 100644 --- a/ui/component/common/premium-badge.jsx +++ b/ui/component/common/premium-badge.jsx @@ -28,7 +28,7 @@ export default function PremiumBadge(props: Props) { {badgeToShow === 'silver' ? ( ) : ( - badgeToShow === 'gold' && + badgeToShow === 'gold' && )} ); @@ -42,11 +42,5 @@ type WrapperProps = { const BadgeWrapper = (props: WrapperProps) => { const { linkPage, children } = props; - return linkPage ? ( - - ) : ( - children - ); + return linkPage ? : children; }; diff --git a/ui/component/membershipSplash/view.jsx b/ui/component/membershipSplash/view.jsx index 28cccd0ce..066a77f0d 100644 --- a/ui/component/membershipSplash/view.jsx +++ b/ui/component/membershipSplash/view.jsx @@ -90,11 +90,11 @@ export default function MembershipSplash(props: Props) {
{__('A MONTH')}, - currencyToUseString: premiumDisplayAmounts[currencyToUse], + premium_recurrence:
{__('A MONTH')}
, + premium_price: premiumDisplayAmounts[currencyToUse], }} > - %currencyToUseString% %date_range% + %premium_price% %premium_recurrence% --[context: '99¢ A MONTH']--
@@ -120,8 +120,14 @@ export default function MembershipSplash(props: Props) {
- {premiumPlusDisplayAmounts[currencyToUse]} -
{__('A MONTH')}
+ {__('A MONTH')}
, + premium_price: premiumPlusDisplayAmounts[currencyToUse], + }} + > + %premium_price% %premium_recurrence% --[context: '99¢ A MONTH']-- + diff --git a/ui/modal/modalConfirmOdyseeMembership/view.jsx b/ui/modal/modalConfirmOdyseeMembership/view.jsx index 86e3ab4cf..0aa2fa1f2 100644 --- a/ui/modal/modalConfirmOdyseeMembership/view.jsx +++ b/ui/modal/modalConfirmOdyseeMembership/view.jsx @@ -143,7 +143,7 @@ export default function ConfirmOdyseeMembershipPurchase(props: Props) { diff --git a/ui/page/odyseeMembership/view.jsx b/ui/page/odyseeMembership/view.jsx index 4118c29d4..fb03fe01c 100644 --- a/ui/page/odyseeMembership/view.jsx +++ b/ui/page/odyseeMembership/view.jsx @@ -233,74 +233,58 @@ const OdyseeMembershipPage = (props: Props) => { // generate different strings depending on other conditions if (plan === 'Premium' && !noChannelsOrIncognitoMode) { featureString = ( - {userChannelName}, - }} - > - Your badge will be shown for your %user_channel_name% channel in all areas of the app, and can be added to two + {userChannelName} }}> + Your badge will be shown for your %channel_name% channel in all areas of the app, and can be added to two additional channels in the future for free. ); } else if (plan === 'Premium+' && !noChannelsOrIncognitoMode) { // user has channel selected featureString = ( - {userChannelName}, - }} - > - The no ads feature applies site-wide for all channels and your badge will be shown for your - %user_channel_name% channel in all areas of the app, and can be added to two additional channels in the future - for free. + {userChannelName} }}> + The no ads feature applies site-wide for all channels and your badge will be shown for your %channel_name% + channel in all areas of the app, and can be added to two additional channels in the future for free. ); } else if (plan === 'Premium' && !channels) { // user has no channels - featureString = - 'You currently have no channels. To show your badge on a channel, please create a channel first. ' + - 'If you register a channel later you will be able to show a badge for up to three channels.'; + featureString = __( + 'You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.' + ); } else if (plan === 'Premium+' && !channels) { // user has no channels - featureString = - 'The no ads feature applies site-wide. You currently have no channels. To show your badge on a channel, please create a channel first. ' + - 'If you register a channel later you will be able to show a badge for up to three channels.'; + featureString = __( + 'The no ads feature applies site-wide. You currently have no channels. To show your badge on a channel, please create a channel first. If you register a channel later you will be able to show a badge for up to three channels.' + ); } else if (plan === 'Premium' && incognito) { // user has incognito selected - featureString = - 'You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, ' + - 'or you can show a badge for up to three channels in the future for free.'; + featureString = __( + 'You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.' + ); } else if (plan === 'Premium+' && incognito) { // user has incognito selected - featureString = - 'The no ads feature applies site-wide. You currently have no channel selected and will not have a badge be visible, ' + - 'if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.'; + featureString = __( + 'The no ads feature applies site-wide. You currently have no channel selected and will not have a badge be visible, if you want to show a badge you can select a channel now, or you can show a badge for up to three channels in the future for free.' + ); } const priceDisplayString = __( - 'You are purchasing a %displayInterval% %plan% membership, ' + - 'that is active immediately and will renew %displayInterval% at a price of %displayCurrency% %currencySymbol%' + - price / 100 + - '. ', + 'You are purchasing a %monthly_yearly% %plan% membership that is active immediately and will renew %monthly_yearly% at a price of %price%.', { - displayInterval: interval + 'ly', - displayCurrency: currencyToUse.toUpperCase(), - currencySymbol: currencyToUse === 'usd' ? '$' : '€', - plan, + monthly_yearly: interval === 'month' ? __('monthly') : __('yearly'), + price: `${currencyToUse.toUpperCase()} ${currencyToUse === 'usd' ? '$' : '€'}${price / 100}`, } ); - let purchaseString = ( - <> - {priceDisplayString} - {featureString} - {__( - ' You can cancel Premium at any time (no refunds) and you can also close this window and choose a different membership option.' - )} - + const noRefund = __( + 'You can cancel Premium at any time (no refunds) and you can also close this window and choose a different membership option.' ); - return purchaseString; + return ( + <> + {priceDisplayString} {featureString} {noRefund} + + ); } const purchaseMembership = function (e, membershipOption, price) { @@ -419,33 +403,32 @@ const OdyseeMembershipPage = (props: Props) => {

{__( - `First of all, thank you for considering or purchasing a membership, it means a ton to us! A few important details to know: ` + 'First of all, thank you for considering or purchasing a membership, it means a ton to us! A few important details to know:' )}

  • {__( - `Exclusive and early access features include: recommended content on homepage, livestreaming, and the ability to post odysee hyperlinks + images in comments. Account is also automatically eligible for Rewards. More to come later.` + 'Exclusive and early access features include: recommended content on homepage, livestreaming, and the ability to post odysee hyperlinks + images in comments. Account is also automatically eligible for Rewards. More to come later.' )}
  • {__( - `The yearly Premium+ membership has a discount compared to monthly, and Premium is only available yearly.` + 'The yearly Premium+ membership has a discount compared to monthly, and Premium is only available yearly.' )}
  • -
  • {__(`These are limited time rates, so get in early!`)}
  • - +
  • {__('These are limited time rates, so get in early!')}
  • {__( - `There may be higher tiers available in the future for creators and anyone else who wants to support us.` + 'There may be higher tiers available in the future for creators and anyone else who wants to support us.' )}
  • - {__(`Badges will be displayed on a single channel to start, with an option to add on two more later on.`)} + {__('Badges will be displayed on a single channel to start, with an option to add on two more later on.')}
  • - {__(`Cannot upgrade or downgrade a membership at this time. Refunds are not available. Choose wisely.`)} + {__('Cannot upgrade or downgrade a membership at this time. Refunds are not available. Choose wisely.')}

@@ -478,7 +461,7 @@ const OdyseeMembershipPage = (props: Props) => { /> } title={__('Get More Information')} - subtitle={<>{__(`Expand to learn more about how Odysee Premium works`)} } + subtitle={__('Expand to learn more about how Odysee Premium works')} actions={showHelp && helpText} className={'premium-explanation-text'} /> @@ -537,8 +520,8 @@ const OdyseeMembershipPage = (props: Props) => { membership-subscription-period={membershipOption.Membership.type} price-id={price.id} className="membership_button" - label={__('Join via %displayInterval% membership', { - displayInterval: price.recurring.interval, + label={__('Join via %interval% membership', { + interval: price.recurring.interval, })} icon={ICONS.FINANCE} interval={price.recurring.interval} @@ -571,9 +554,7 @@ const OdyseeMembershipPage = (props: Props) => {
{/*

Active Memberships

*/} {!stillWaitingFromBackend && activeMemberships && activeMemberships.length === 0 && ( - <> -

{__('You currently have no active memberships')}

- +

{__('You currently have no active memberships')}

)} {/** active memberships **/} {!stillWaitingFromBackend && @@ -594,7 +575,7 @@ const OdyseeMembershipPage = (props: Props) => { {/* registered on */}

- {__('Registered On:')} {formatDate(membership.Membership.created_at)} + {__('Registered On')}: {formatDate(membership.Membership.created_at)}

{/* autorenews at */} @@ -606,12 +587,14 @@ const OdyseeMembershipPage = (props: Props) => { {!stillWaitingFromBackend && membership.type === 'yearly' && ( <>

- {__('Membership Period Options:')} {__('Yearly')} + {__('Membership Period Options')}: {__('Yearly')}

{/* TODO: this looks wrong, should support EUR as well */}

- ${(membership.cost_usd * 12) / 100} {__('USD For A One Year Membership')} ($ - {membership.cost_usd / 100} {__('Per Month')}) + {__('%yearly_cost% USD For A One Year Membership (%monthly_cost% Per Month)', { + yearly_cost: (membership.cost_usd * 12) / 100, + monthly_cost: membership.cost_usd / 100, + })}

)} @@ -636,9 +619,7 @@ const OdyseeMembershipPage = (props: Props) => {
{canceledMemberships && canceledMemberships.length === 0 && ( - <> -

{__('You currently have no canceled memberships')}

- +

{__('You currently have no canceled memberships')}

)} {canceledMemberships && canceledMemberships.map((membership) => ( @@ -706,13 +687,11 @@ const OdyseeMembershipPage = (props: Props) => { {/** clear membership data (only available on dev) **/} {isDev && cardSaved && purchasedMemberships.length > 0 && ( <> -

- {__('Clear Membership Data (Only Available On Dev)')} -

+

Clear Membership Data (Only Available On Dev)