diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 8e6a701f6c1a..1467e8bf47f2 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -3,10 +3,12 @@ 22.2 ----- * [**] [Jetpack-only] Adds a dashboard card for purchasing domains. [https://github.com/wordpress-mobile/WordPress-Android/pull/18240] +* [**] [Jetpack-only] Blogging Prompts: adds the ability to view other users' responses to a prompt. [https://github.com/wordpress-mobile/WordPress-Android/pull/18265] 22.1 ----- * [**] [WordPress-only] Warns user about sites with only individual plugins not supporting core app features and offers the option to switch to the Jetpack app. [https://github.com/wordpress-mobile/WordPress-Android/pull/18199] +* [*] Block editor: Avoid empty Gallery block error [https://github.com/WordPress/gutenberg/pull/49557] 22.0 ----- diff --git a/WordPress/src/androidTest/java/org/wordpress/android/e2e/ReaderTests.kt b/WordPress/src/androidTest/java/org/wordpress/android/e2e/ReaderTests.kt index e353e82ae306..f9706f5905b9 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/e2e/ReaderTests.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/e2e/ReaderTests.kt @@ -21,18 +21,16 @@ class ReaderTests : BaseTest() { ReaderPage().go() } - var mCoachingPostTitle = "Let's check out the coaching team!" - var mCompetitionPostTitle = "Let's focus on the competition." @Test fun e2eNavigateThroughPosts() { ReaderPage() .tapFollowingTab() - .openPost(mCoachingPostTitle) - .verifyPostDisplayed(mCoachingPostTitle) + .openBlogOrPost(TITLE_COACHING_POST) + .verifyPostDisplayed(TITLE_COACHING_POST) .slideToPreviousPost() - .verifyPostDisplayed(mCompetitionPostTitle) + .verifyPostDisplayed(TITLE_COMPETITION_POST) .slideToNextPost() - .verifyPostDisplayed(mCoachingPostTitle) + .verifyPostDisplayed(TITLE_COACHING_POST) .goBackToReader() } @@ -40,11 +38,29 @@ class ReaderTests : BaseTest() { fun e2eLikePost() { ReaderPage() .tapFollowingTab() - .openPost(mCoachingPostTitle) + .openBlogOrPost(TITLE_COACHING_POST) .likePost() .verifyPostLiked() .unlikePost() .verifyPostNotLiked() .goBackToReader() } + + @Test + fun e2eBookmarkPost() { + ReaderPage() + .tapFollowingTab() + .openBlogOrPost(TITLE_LONGREADS_BLOG) + .bookmarkPost() + .verifyPostBookmarked() + .removeBookmarkPost() + .verifyPostNotBookmarked() + .goBackToReader() + } + + companion object { + private const val TITLE_LONGREADS_BLOG = "Longreads" + private const val TITLE_COACHING_POST = "Let's check out the coaching team!" + private const val TITLE_COMPETITION_POST = "Let's focus on the competition." + } } diff --git a/WordPress/src/androidTest/java/org/wordpress/android/e2e/StatsTests.kt b/WordPress/src/androidTest/java/org/wordpress/android/e2e/StatsTests.kt index 96fdeaff0c02..380862080c0c 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/e2e/StatsTests.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/e2e/StatsTests.kt @@ -4,8 +4,10 @@ import androidx.test.espresso.Espresso import androidx.test.espresso.matcher.ViewMatchers import dagger.hilt.android.testing.HiltAndroidTest import org.junit.After +import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test +import org.wordpress.android.BuildConfig import org.wordpress.android.R import org.wordpress.android.e2e.pages.MySitesPage import org.wordpress.android.support.BaseTest @@ -33,6 +35,10 @@ class StatsTests : BaseTest() { @Test fun e2eAllDayStatsLoad() { + // We're not running this test on JP. + // See https://github.com/wordpress-mobile/WordPress-Android/issues/18065 + assumeTrue(!BuildConfig.IS_JETPACK_APP) + val todayVisits = StatsVisitsData("97", "28", "14", "11") val postsList: List = StatsMocksReader().readDayTopPostsToList() val referrersList: List = StatsMocksReader().readDayTopReferrersToList() diff --git a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderPage.kt b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderPage.kt index 15fc175dafd4..3756d7e54e97 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderPage.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderPage.kt @@ -16,7 +16,7 @@ class ReaderPage { return this } - fun openPost(postTitle: String?): ReaderViewPage { + fun openBlogOrPost(postTitle: String): ReaderViewPage { val post = Espresso.onView(ViewMatchers.withChild(ViewMatchers.withText(postTitle))) WPSupportUtils.scrollIntoView(R.id.reader_recycler_view, post, 1f) WPSupportUtils.clickOn(postTitle) diff --git a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderViewPage.kt b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderViewPage.kt index aed5f4c374a8..97d863fc79c4 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderViewPage.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/ReaderViewPage.kt @@ -3,58 +3,88 @@ package org.wordpress.android.e2e.pages import android.view.KeyEvent import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import junit.framework.TestCase import org.wordpress.android.support.WPSupportUtils class ReaderViewPage { - var mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - var mLikerContainerId = "org.wordpress.android.prealpha:id/liker_faces_container" - var mRelatedPostsId = "org.wordpress.android.prealpha:id/container_related_posts" - var mFooterId = "org.wordpress.android.prealpha:id/layout_post_detail_footer" - var mLikerContainer = mDevice.findObject(UiSelector().resourceId(mLikerContainerId)) - var mRelatedPostsContainer = mDevice.findObject(UiSelector().resourceId(mRelatedPostsId)) - var mSwipeForMore = mDevice.findObject(UiSelector().textContains("Swipe for more")) - var mFooter = mDevice.findObject(UiSelector().resourceId(mFooterId)) + private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + private val likerContainer = device.findObject(UiSelector().resourceId(buildResourceId("liker_faces_container"))) + private val relatedPostsContainer = device.findObject( + UiSelector().resourceId(buildResourceId("container_related_posts")) + ) + private val swipeForMore = device.findObject(UiSelector().textContains("Swipe for more")) + private val recyclerView = UiScrollable(UiSelector().resourceId(buildResourceId("recycler_view"))) + private val savePostsForLater = device.findObject(UiSelector().text("Save Posts for Later")) + private val okButton = device.findObject(UiSelector().text("OK")) + private val bookmarkButtonSelector = UiSelector().resourceId(buildResourceId("bookmark")) + + private fun buildResourceId(id: String): String { + val packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName + return "$packageName:id/$id" + } + fun waitUntilLoaded(): ReaderViewPage { - mRelatedPostsContainer.waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) + relatedPostsContainer.waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) return this } fun likePost(): ReaderViewPage { tapLikeButton() - mLikerContainer.waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) + likerContainer.waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) return this } fun unlikePost(): ReaderViewPage { tapLikeButton() - mLikerContainer.waitUntilGone(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) + likerContainer.waitUntilGone(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) return this } private fun tapLikeButton() { - mSwipeForMore.waitUntilGone(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) + swipeForMore.waitUntilGone(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) // Even though it was working locally in simulator, tapping the footer buttons, // like 'mLikeButton.click()', was not working in CI. // The current workaround is to use arrows navigation. // Bring focus to the footer. First button is selected. - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN) // Navigate to Like button. - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) // Click the Like button. - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER) // Navigate back to the first footer button. - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) - mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) + device.pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT) + } + + fun bookmarkPost(): ReaderViewPage { + tapBookmarkButton() + // Dismiss save posts locally dialog. + if (savePostsForLater.exists()) { + okButton.clickAndWaitForNewWindow() + } + return this + } + + fun removeBookmarkPost(): ReaderViewPage { + tapBookmarkButton() + return this + } + + private fun tapBookmarkButton() { + // Scroll to the bookmark button. + recyclerView.scrollIntoView(bookmarkButtonSelector) + // Tap the bookmark button. + device.findObject(bookmarkButtonSelector).clickAndWaitForNewWindow() } fun goBackToReader(): ReaderPage { - mDevice.pressBack() + device.pressBack() return ReaderPage() } @@ -77,7 +107,7 @@ class ReaderViewPage { } fun verifyPostLiked(): ReaderViewPage { - val isLiked = mDevice + val isLiked = device .findObject(UiSelector().textContains("You like this.")) .waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) TestCase.assertTrue("Liker was not displayed.", isLiked) @@ -85,8 +115,21 @@ class ReaderViewPage { } fun verifyPostNotLiked(): ReaderViewPage { - val likerDisplayed = mLikerContainer.exists() + val likerDisplayed = likerContainer.exists() TestCase.assertFalse("Liker faces container was displayed.", likerDisplayed) return this } + + fun verifyPostBookmarked(): ReaderViewPage { + val isBookmarked = device.findObject(UiSelector().text("Post saved")) + .waitForExists(WPSupportUtils.DEFAULT_TIMEOUT.toLong()) + TestCase.assertTrue("Snackbar was not displayed.", isBookmarked) + return this + } + + fun verifyPostNotBookmarked(): ReaderViewPage { + val isBookmarked = device.findObject(bookmarkButtonSelector).isSelected + TestCase.assertFalse("The bookmark button is selected", isBookmarked) + return this + } } diff --git a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/StatsPage.kt b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/StatsPage.kt index cc39fae61d96..0f515bfdc26a 100644 --- a/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/StatsPage.kt +++ b/WordPress/src/androidTest/java/org/wordpress/android/e2e/pages/StatsPage.kt @@ -5,7 +5,6 @@ import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.matcher.ViewMatchers import org.hamcrest.Matchers -import org.wordpress.android.BuildConfig import org.wordpress.android.R import org.wordpress.android.support.WPSupportUtils import org.wordpress.android.util.StatsKeyValueData @@ -67,41 +66,37 @@ class StatsPage { } fun assertVisits(visitsData: StatsVisitsData): StatsPage { - // Skip this check for JP because of the bug with Stats card load. - // See https://github.com/wordpress-mobile/WordPress-Android/issues/18065 - if (!BuildConfig.IS_JETPACK_APP) { - val cardStructure = Espresso.onView( - Matchers.allOf( - ViewMatchers.isDescendantOfA(visibleCoordinatorLayout), - ViewMatchers.withId(R.id.stats_block_list), - ViewMatchers.hasDescendant( - Matchers.allOf( - ViewMatchers.withText("Views"), - ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.views)) - ) - ), - ViewMatchers.hasDescendant( - Matchers.allOf( - ViewMatchers.withText("Visitors"), - ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.visitors)) - ) - ), - ViewMatchers.hasDescendant( - Matchers.allOf( - ViewMatchers.withText("Likes"), - ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.likes)) - ) - ), - ViewMatchers.hasDescendant( - Matchers.allOf( - ViewMatchers.withText("Comments"), - ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.comments)) - ) + val cardStructure = Espresso.onView( + Matchers.allOf( + ViewMatchers.isDescendantOfA(visibleCoordinatorLayout), + ViewMatchers.withId(R.id.stats_block_list), + ViewMatchers.hasDescendant( + Matchers.allOf( + ViewMatchers.withText("Views"), + ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.views)) + ) + ), + ViewMatchers.hasDescendant( + Matchers.allOf( + ViewMatchers.withText("Visitors"), + ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.visitors)) + ) + ), + ViewMatchers.hasDescendant( + Matchers.allOf( + ViewMatchers.withText("Likes"), + ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.likes)) + ) + ), + ViewMatchers.hasDescendant( + Matchers.allOf( + ViewMatchers.withText("Comments"), + ViewMatchers.hasSibling(ViewMatchers.withText(visitsData.comments)) ) ) ) - cardStructure.check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed())) - } + ) + cardStructure.check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed())) return this } diff --git a/WordPress/src/main/java/org/wordpress/android/modules/AppComponent.java b/WordPress/src/main/java/org/wordpress/android/modules/AppComponent.java index 7bf3acf80190..be4024ac52ca 100644 --- a/WordPress/src/main/java/org/wordpress/android/modules/AppComponent.java +++ b/WordPress/src/main/java/org/wordpress/android/modules/AppComponent.java @@ -136,7 +136,6 @@ import org.wordpress.android.ui.reader.CommentNotificationsBottomSheetFragment; import org.wordpress.android.ui.reader.ReaderBlogFragment; import org.wordpress.android.ui.reader.ReaderPostDetailFragment; -import org.wordpress.android.ui.reader.ReaderPostListActivity; import org.wordpress.android.ui.reader.ReaderPostListFragment; import org.wordpress.android.ui.reader.ReaderPostPagerActivity; import org.wordpress.android.ui.reader.ReaderSearchActivity; @@ -342,8 +341,6 @@ public interface AppComponent { void inject(ReaderPostPagerActivity object); - void inject(ReaderPostListActivity object); - void inject(ReaderBlogFragment object); void inject(ReaderBlogAdapter object); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainProductDetails.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainProductDetails.kt index 054ad9c81517..b6eaad296252 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainProductDetails.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainProductDetails.kt @@ -1,11 +1,9 @@ package org.wordpress.android.ui.domains -import android.annotation.SuppressLint import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize -@SuppressLint("ParcelCreator") data class DomainProductDetails( val productId: Int, val domainName: String diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt index 33de362b3ab1..9481a6e11951 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt @@ -25,7 +25,6 @@ import org.wordpress.android.util.AppLog.T import org.wordpress.android.util.SiteUtils import org.wordpress.android.util.config.SiteDomainsFeatureConfig import org.wordpress.android.util.extensions.isOnSale -import org.wordpress.android.util.extensions.saleCostForDisplay import org.wordpress.android.util.helpers.Debouncer import org.wordpress.android.viewmodel.Event import org.wordpress.android.viewmodel.ScopedViewModel @@ -186,7 +185,7 @@ class DomainSuggestionsViewModel @Inject constructor( domainName = it.domain_name, cost = it.cost, isOnSale = product.isOnSale(), - saleCost = product.saleCostForDisplay(), + saleCost = product?.combinedSaleCostDisplay.orEmpty(), isFree = it.is_free, supportsPrivacy = it.supports_privacy, productId = it.product_id, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSource.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSource.kt index c26cc5057fe1..4dd949973f7c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSource.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSource.kt @@ -15,6 +15,7 @@ import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.MySiteSource.MySiteRefreshSource import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.util.config.DashboardCardActivityLogConfig import org.wordpress.android.util.config.DashboardCardPagesConfig import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig import javax.inject.Inject @@ -27,12 +28,15 @@ class CardsSource @Inject constructor( private val cardsStore: CardsStore, todaysStatsCardFeatureConfig: MySiteDashboardTodaysStatsCardFeatureConfig, dashboardCardPagesConfig: DashboardCardPagesConfig, + dashboardCardActivityLogConfig: DashboardCardActivityLogConfig, @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher ) : MySiteRefreshSource { private val isTodaysStatsCardFeatureConfigEnabled = todaysStatsCardFeatureConfig.isEnabled() private val isDashboardCardPagesConfigEnabled = dashboardCardPagesConfig.isEnabled() + private val isDashboardCardActivityLogConfigEnabled = dashboardCardActivityLogConfig.isEnabled() + override val refresh = MutableLiveData(false) override fun build(coroutineScope: CoroutineScope, siteLocalId: Int): LiveData { @@ -104,6 +108,7 @@ class CardsSource @Inject constructor( private fun getCardTypes() = mutableListOf().apply { if (isTodaysStatsCardFeatureConfigEnabled) add(Type.TODAYS_STATS) if (isDashboardCardPagesConfigEnabled) add(Type.PAGES) + if (isDashboardCardActivityLogConfigEnabled) add(Type.ACTIVITY) add(Type.POSTS) }.toList() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java index 9f3a8e422bfe..8f6df01769f0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java @@ -46,9 +46,12 @@ import javax.inject.Inject; +import dagger.hilt.android.AndroidEntryPoint; + /* * serves as the host for ReaderPostListFragment when showing blog preview & tag preview */ +@AndroidEntryPoint public class ReaderPostListActivity extends LocaleAwareActivity { private String mSource; private ReaderPostListType mPostListType; @@ -65,7 +68,6 @@ public class ReaderPostListActivity extends LocaleAwareActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ((WordPress) getApplication()).component().inject(this); setContentView(R.layout.reader_activity_post_list); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt index 457c07c6ff4f..59a4c1f3d0a6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt @@ -7,6 +7,7 @@ import android.view.MenuItem import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.fragment.app.Fragment +import androidx.fragment.app.commit import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.cancel import org.wordpress.android.R @@ -15,6 +16,7 @@ import org.wordpress.android.ui.ActivityLauncherWrapper import org.wordpress.android.ui.ActivityLauncherWrapper.Companion.JETPACK_PACKAGE_NAME import org.wordpress.android.ui.LocaleAwareActivity import org.wordpress.android.ui.accounts.HelpActivity.Origin +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewActivity.OpenCheckout import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureFullScreenOverlayFragment import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureFullScreenOverlayViewModel import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureOverlayActions.DismissDialog @@ -26,21 +28,24 @@ import org.wordpress.android.ui.posts.BasicFragmentDialog.BasicDialogPositiveCli import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleEmpty import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleGeneral import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleStepCount +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Completed +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched import org.wordpress.android.ui.sitecreation.SiteCreationStep.DOMAINS import org.wordpress.android.ui.sitecreation.SiteCreationStep.INTENTS +import org.wordpress.android.ui.sitecreation.SiteCreationStep.PROGRESS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_DESIGNS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_NAME import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_PREVIEW +import org.wordpress.android.ui.sitecreation.domains.DomainModel import org.wordpress.android.ui.sitecreation.domains.DomainsScreenListener import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsFragment import org.wordpress.android.ui.sitecreation.misc.OnHelpClickedListener import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource import org.wordpress.android.ui.sitecreation.previews.SiteCreationPreviewFragment -import org.wordpress.android.ui.sitecreation.previews.SitePreviewScreenListener -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteCreationCompleted -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotCreated -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotInLocalDb +import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressFragment +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel import org.wordpress.android.ui.sitecreation.sitename.SiteCreationSiteNameFragment import org.wordpress.android.ui.sitecreation.sitename.SiteCreationSiteNameViewModel import org.wordpress.android.ui.sitecreation.sitename.SiteNameScreenListener @@ -63,7 +68,6 @@ class SiteCreationActivity : LocaleAwareActivity(), IntentsScreenListener, SiteNameScreenListener, DomainsScreenListener, - SitePreviewScreenListener, OnHelpClickedListener, BasicDialogPositiveClickInterface, BasicDialogNegativeClickInterface { @@ -77,8 +81,14 @@ class SiteCreationActivity : LocaleAwareActivity(), private val siteCreationIntentsViewModel: SiteCreationIntentsViewModel by viewModels() private val siteCreationSiteNameViewModel: SiteCreationSiteNameViewModel by viewModels() private val jetpackFullScreenViewModel: JetpackFeatureFullScreenOverlayViewModel by viewModels() - @Inject internal lateinit var jetpackFeatureRemovalOverlayUtil: JetpackFeatureRemovalOverlayUtil - @Inject internal lateinit var activityLauncherWrapper: ActivityLauncherWrapper + private val progressViewModel: SiteCreationProgressViewModel by viewModels() + private val previewViewModel: SitePreviewViewModel by viewModels() + + @Inject + internal lateinit var jetpackFeatureRemovalOverlayUtil: JetpackFeatureRemovalOverlayUtil + + @Inject + internal lateinit var activityLauncherWrapper: ActivityLauncherWrapper private val backPressedCallback = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { @@ -86,6 +96,10 @@ class SiteCreationActivity : LocaleAwareActivity(), } } + private val domainCheckoutActivityLauncher = registerForActivityResult(OpenCheckout()) { + mainViewModel.onCheckoutResult(it) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.site_creation_activity) @@ -105,30 +119,16 @@ class SiteCreationActivity : LocaleAwareActivity(), @Suppress("LongMethod") private fun observeVMState() { - mainViewModel.navigationTargetObservable - .observe(this) { target -> target?.let { showStep(target) } } - mainViewModel.wizardFinishedObservable.observe(this) { createSiteState -> - createSiteState?.let { - val intent = Intent() - val (siteCreated, localSiteId, titleTaskComplete) = when (createSiteState) { - // site creation flow was canceled - is SiteNotCreated -> Triple(false, null, false) - is SiteNotInLocalDb -> { - // Site was created, but we haven't been able to fetch it, let `SitePickerActivity` handle - // this with a Snackbar message. - intent.putExtra(SitePickerActivity.KEY_SITE_CREATED_BUT_NOT_FETCHED, true) - Triple(true, null, createSiteState.isSiteTitleTaskComplete) - } - is SiteCreationCompleted -> Triple( - true, createSiteState.localSiteId, - createSiteState.isSiteTitleTaskComplete - ) - } - intent.putExtra(SitePickerActivity.KEY_SITE_LOCAL_ID, localSiteId) - intent.putExtra(SitePickerActivity.KEY_SITE_TITLE_TASK_COMPLETED, titleTaskComplete) - setResult(if (siteCreated) Activity.RESULT_OK else Activity.RESULT_CANCELED, intent) - finish() + mainViewModel.navigationTargetObservable.observe(this) { it?.let(::showStep) } + mainViewModel.onCompleted.observe(this) { (result, isTitleTaskComplete) -> + val intent = Intent().apply { + putExtra(SitePickerActivity.KEY_SITE_LOCAL_ID, (result as? Created)?.site?.id) + putExtra(SitePickerActivity.KEY_SITE_TITLE_TASK_COMPLETED, isTitleTaskComplete) + // Let `SitePickerActivity` handle this with a SnackBar message + putExtra(SitePickerActivity.KEY_SITE_CREATED_BUT_NOT_FETCHED, result is CreatedButNotFetched) } + setResult(if (result is Completed) Activity.RESULT_OK else Activity.RESULT_CANCELED, intent) + finish() } mainViewModel.dialogActionObservable.observe(this) { it?.show(this, supportFragmentManager, uiHelpers) @@ -141,6 +141,7 @@ class SiteCreationActivity : LocaleAwareActivity(), ActivityUtils.hideKeyboard(this) onBackPressedDispatcher.onBackPressedCompat(backPressedCallback) } + mainViewModel.showDomainCheckout.observe(this, domainCheckoutActivityLauncher::launch) siteCreationIntentsViewModel.onBackButtonPressed.observe(this) { mainViewModel.onBackPressed() } @@ -161,16 +162,23 @@ class SiteCreationActivity : LocaleAwareActivity(), hppViewModel.onDesignActionPressed.observe(this) { design -> mainViewModel.onSiteDesignSelected(design.template) } - + progressViewModel.onCancelWizardClicked.observe(this) { + mainViewModel.onWizardCancelled() + } + progressViewModel.onFreeSiteCreated.observe(this, mainViewModel::onFreeSiteCreated) + progressViewModel.onCartCreated.observe(this, mainViewModel::onCartCreated) + previewViewModel.onOkButtonClicked.observe(this) { result -> + mainViewModel.onWizardFinished(result) + } observeOverlayEvents() } private fun observeOverlayEvents() { val fragment = JetpackFeatureFullScreenOverlayFragment - .newInstance( - isSiteCreationOverlay = true, - siteCreationSource = getSiteCreationSource() - ) + .newInstance( + isSiteCreationOverlay = true, + siteCreationSource = getSiteCreationSource() + ) jetpackFullScreenViewModel.action.observe(this) { action -> if (mainViewModel.siteCreationDisabled) finish() @@ -188,7 +196,7 @@ class SiteCreationActivity : LocaleAwareActivity(), mainViewModel.showJetpackOverlay.observeEvent(this) { if (mainViewModel.siteCreationDisabled) - slideInFragment(fragment, JetpackFeatureFullScreenOverlayFragment.TAG) + showFragment(fragment, JetpackFeatureFullScreenOverlayFragment.TAG) else fragment.show(supportFragmentManager, JetpackFeatureFullScreenOverlayFragment.TAG) } } @@ -210,18 +218,10 @@ class SiteCreationActivity : LocaleAwareActivity(), ActivityUtils.hideKeyboard(this) } - override fun onDomainSelected(domain: String) { + override fun onDomainSelected(domain: DomainModel) { mainViewModel.onDomainsScreenFinished(domain) } - override fun onSiteCreationCompleted() { - mainViewModel.onSiteCreationCompleted() - } - - override fun onSitePreviewScreenDismissed(createSiteState: CreateSiteState) { - mainViewModel.onSitePreviewScreenFinished(createSiteState) - } - override fun onHelpClicked(origin: Origin) { ActivityLauncher.viewHelp(this, origin, null, null) } @@ -236,12 +236,11 @@ class SiteCreationActivity : LocaleAwareActivity(), mainViewModel.preloadingJob?.cancel("Preload did not complete before theme picker was shown.") HomePagePickerFragment.newInstance(target.wizardState.siteIntent) } - DOMAINS -> SiteCreationDomainsFragment.newInstance( - screenTitle - ) + DOMAINS -> SiteCreationDomainsFragment.newInstance(screenTitle) + PROGRESS -> SiteCreationProgressFragment.newInstance(target.wizardState) SITE_PREVIEW -> SiteCreationPreviewFragment.newInstance(screenTitle, target.wizardState) } - slideInFragment(fragment, target.wizardStep.toString()) + showFragment(fragment, target.wizardStep.toString(), target.wizardStep != SITE_PREVIEW) } private fun getScreenTitle(step: SiteCreationStep): String { @@ -256,17 +255,22 @@ class SiteCreationActivity : LocaleAwareActivity(), } } - private fun slideInFragment(fragment: Fragment, tag: String) { - val fragmentTransaction = supportFragmentManager.beginTransaction() - if (supportFragmentManager.findFragmentById(R.id.fragment_container) != null) { - // add to back stack and animate all screen except of the first one - fragmentTransaction.addToBackStack(null).setCustomAnimations( - R.anim.activity_slide_in_from_right, R.anim.activity_slide_out_to_left, - R.anim.activity_slide_in_from_left, R.anim.activity_slide_out_to_right - ) + private fun showFragment(fragment: Fragment, tag: String, slideIn: Boolean = true) { + supportFragmentManager.commit { + if (supportFragmentManager.findFragmentById(R.id.fragment_container) != null) { + // add to back stack and animate all screen except of the first one + addToBackStack(null) + if (slideIn) { + setCustomAnimations( + R.anim.activity_slide_in_from_right, R.anim.activity_slide_out_to_left, + R.anim.activity_slide_in_from_left, R.anim.activity_slide_out_to_right + ) + } else { + setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out) + } + } + replace(R.id.fragment_container, fragment, tag) } - fragmentTransaction.replace(R.id.fragment_container, fragment, tag) - fragmentTransaction.commit() } override fun onPositiveClicked(instanceTag: String) { @@ -287,5 +291,6 @@ class SiteCreationActivity : LocaleAwareActivity(), companion object { const val ARG_CREATE_SITE_SOURCE = "ARG_CREATE_SITE_SOURCE" + const val ARG_STATE = "ARG_SITE_CREATION_STATE" } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt index 6190a3fefaff..29b46106c5b8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt @@ -1,6 +1,5 @@ package org.wordpress.android.ui.sitecreation -import android.annotation.SuppressLint import android.content.Context import android.os.Bundle import android.os.Parcelable @@ -17,14 +16,22 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.wordpress.android.R import org.wordpress.android.fluxc.Dispatcher +import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.networking.MShot +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewActivity.OpenCheckout.CheckoutDetails +import org.wordpress.android.ui.domains.DomainRegistrationCompletedEvent +import org.wordpress.android.ui.domains.DomainsRegistrationTracker import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleEmpty import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleGeneral import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleStepCount +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Completed +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched +import org.wordpress.android.ui.sitecreation.SiteCreationResult.NotCreated +import org.wordpress.android.ui.sitecreation.domains.DomainModel import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState import org.wordpress.android.ui.sitecreation.usecases.FetchHomePageLayoutsUseCase import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.util.AppLog @@ -45,21 +52,55 @@ import javax.inject.Inject const val TAG_WARNING_DIALOG = "back_pressed_warning_dialog" const val KEY_CURRENT_STEP = "key_current_step" -const val KEY_SITE_CREATION_COMPLETED = "key_site_creation_completed" const val KEY_SITE_CREATION_STATE = "key_site_creation_state" @Parcelize -@SuppressLint("ParcelCreator") data class SiteCreationState( val siteIntent: String? = null, val siteName: String? = null, val segmentId: Long? = null, val siteDesign: String? = null, - val domain: String? = null + val domain: DomainModel? = null, + val result: SiteCreationResult = NotCreated, ) : WizardState, Parcelable typealias NavigationTarget = WizardNavigationTarget +sealed interface SiteCreationResult : Parcelable { + @Parcelize + object NotCreated : SiteCreationResult + + sealed interface Created: SiteCreationResult { + val site: SiteModel + } + + sealed interface CreatedButNotFetched : Created { + @Parcelize + data class NotInLocalDb( + override val site: SiteModel, + ) : CreatedButNotFetched + + @Parcelize + data class InCart( + override val site: SiteModel, + ) : CreatedButNotFetched + + @Parcelize + data class DomainRegistrationPurchased( + val domainName: String, + val email: String, + override val site: SiteModel, + ) : CreatedButNotFetched + } + + @Parcelize + data class Completed( + override val site: SiteModel, + ) : Created +} + +typealias SiteCreationCompletionEvent = Pair + @HiltViewModel class SiteCreationMainVM @Inject constructor( private val tracker: SiteCreationTracker, @@ -71,6 +112,7 @@ class SiteCreationMainVM @Inject constructor( private val jetpackFeatureRemovalOverlayUtil: JetpackFeatureRemovalOverlayUtil, private val domainPurchasingExperiment: SiteCreationDomainPurchasingExperiment, private val domainPurchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig, + private val domainsRegistrationTracker: DomainsRegistrationTracker, ) : ViewModel() { init { dispatcher.register(fetchHomePageLayoutsUseCase) @@ -83,7 +125,6 @@ class SiteCreationMainVM @Inject constructor( var siteCreationDisabled: Boolean = false private var isStarted = false - private var siteCreationCompleted = false private lateinit var siteCreationState: SiteCreationState @@ -101,8 +142,8 @@ class SiteCreationMainVM @Inject constructor( private val _dialogAction = SingleLiveEvent() val dialogActionObservable: LiveData = _dialogAction - private val _wizardFinishedObservable = SingleLiveEvent() - val wizardFinishedObservable: LiveData = _wizardFinishedObservable + private val _onCompleted = SingleLiveEvent() + val onCompleted: LiveData = _onCompleted private val _exitFlowObservable = SingleLiveEvent() val exitFlowObservable: LiveData = _exitFlowObservable @@ -113,6 +154,9 @@ class SiteCreationMainVM @Inject constructor( private val _showJetpackOverlay = MutableLiveData>() val showJetpackOverlay: LiveData> = _showJetpackOverlay + private val _showDomainCheckout = SingleLiveEvent() + val showDomainCheckout: LiveData = _showDomainCheckout + fun start(savedInstanceState: Bundle?, siteCreationSource: SiteCreationSource) { if (isStarted) return if (savedInstanceState == null) { @@ -128,7 +172,6 @@ class SiteCreationMainVM @Inject constructor( else showSiteCreationNextStep() } else { - siteCreationCompleted = savedInstanceState.getBoolean(KEY_SITE_CREATION_COMPLETED, false) siteCreationState = requireNotNull(savedInstanceState.getParcelableCompat(KEY_SITE_CREATION_STATE)) val currentStepIndex = savedInstanceState.getInt(KEY_CURRENT_STEP) wizardManager.setCurrentStepIndex(currentStepIndex) @@ -170,7 +213,6 @@ class SiteCreationMainVM @Inject constructor( } fun writeToBundle(outState: Bundle) { - outState.putBoolean(KEY_SITE_CREATION_COMPLETED, siteCreationCompleted) outState.putInt(KEY_CURRENT_STEP, wizardManager.currentStep) outState.putParcelable(KEY_SITE_CREATION_STATE, siteCreationState) } @@ -202,7 +244,7 @@ class SiteCreationMainVM @Inject constructor( fun onBackPressed() { return if (wizardManager.isLastStep()) { - if (siteCreationCompleted) { + if (siteCreationState.result is Completed) { exitFlow(false) } else { _dialogAction.value = DialogHolder( @@ -220,18 +262,14 @@ class SiteCreationMainVM @Inject constructor( } private fun clearOldSiteCreationState(wizardStep: SiteCreationStep) { - when (wizardStep) { - SiteCreationStep.SITE_DESIGNS -> Unit // Do nothing - SiteCreationStep.DOMAINS -> siteCreationState.domain?.let { + if (wizardStep == SiteCreationStep.DOMAINS) { + siteCreationState.domain?.let { siteCreationState = siteCreationState.copy(domain = null) } - SiteCreationStep.SITE_PREVIEW -> Unit // Do nothing - SiteCreationStep.INTENTS -> Unit // Do nothing - SiteCreationStep.SITE_NAME -> Unit // Do nothing } } - fun onDomainsScreenFinished(domain: String) { + fun onDomainsScreenFinished(domain: DomainModel) { siteCreationState = siteCreationState.copy(domain = domain) wizardManager.showNextStep() } @@ -255,10 +293,43 @@ class SiteCreationMainVM @Inject constructor( } } - fun onSiteCreationCompleted() { - siteCreationCompleted = true + fun onCartCreated(checkoutDetails: CheckoutDetails) { + siteCreationState = siteCreationState.copy(result = CreatedButNotFetched.InCart(checkoutDetails.site)) + domainsRegistrationTracker.trackDomainsPurchaseWebviewViewed(checkoutDetails.site, isSiteCreation = true) + _showDomainCheckout.value = checkoutDetails + } + + fun onCheckoutResult(event: DomainRegistrationCompletedEvent?) { + if (event == null) return onBackPressed() + siteCreationState = siteCreationState.run { + check(result is CreatedButNotFetched.InCart) + copy( + result = CreatedButNotFetched.DomainRegistrationPurchased( + event.domainName, + event.email, + result.site, + ) + ) + } + wizardManager.showNextStep() } + fun onFreeSiteCreated(site: SiteModel) { + siteCreationState = siteCreationState.copy(result = CreatedButNotFetched.NotInLocalDb(site)) + wizardManager.showNextStep() + } + + fun onWizardCancelled() { + _onCompleted.value = NotCreated to isSiteTitleTaskCompleted() + } + + fun onWizardFinished(result: Created) { + siteCreationState = siteCreationState.copy(result = result) + _onCompleted.value = result to isSiteTitleTaskCompleted() + } + + private fun isSiteTitleTaskCompleted() = !siteCreationState.siteName.isNullOrBlank() + /** * Exits the flow and tracks an event when the user force-exits the "site creation in progress" before it completes. */ @@ -269,26 +340,14 @@ class SiteCreationMainVM @Inject constructor( _exitFlowObservable.call() } - fun onSitePreviewScreenFinished(createSiteState: CreateSiteState) { - _wizardFinishedObservable.value = createSiteState - } - fun onPositiveDialogButtonClicked(instanceTag: String) { - when (instanceTag) { - TAG_WARNING_DIALOG -> { - exitFlow(true) - } - else -> NotImplementedError("Unknown dialog tag: $instanceTag") - } + check(instanceTag == TAG_WARNING_DIALOG) { "Unknown dialog tag: $instanceTag" } + exitFlow(true) } fun onNegativeDialogButtonClicked(instanceTag: String) { - when (instanceTag) { - TAG_WARNING_DIALOG -> { - // do nothing - } - else -> NotImplementedError("Unknown dialog tag: $instanceTag") - } + check(instanceTag == TAG_WARNING_DIALOG) { "Unknown dialog tag: $instanceTag" } + // do nothing } sealed class SiteCreationScreenTitle { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt index c46b0dfda43d..6a2e52a4fead 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt @@ -2,6 +2,7 @@ package org.wordpress.android.ui.sitecreation import org.wordpress.android.ui.sitecreation.SiteCreationStep.DOMAINS import org.wordpress.android.ui.sitecreation.SiteCreationStep.INTENTS +import org.wordpress.android.ui.sitecreation.SiteCreationStep.PROGRESS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_DESIGNS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_NAME import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_PREVIEW @@ -12,7 +13,7 @@ import javax.inject.Inject import javax.inject.Singleton enum class SiteCreationStep : WizardStep { - SITE_DESIGNS, DOMAINS, SITE_PREVIEW, INTENTS, SITE_NAME; + SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW, INTENTS, SITE_NAME; } @Singleton @@ -24,8 +25,8 @@ class SiteCreationStepsProvider @Inject constructor( private val isIntentsEnabled get() = siteIntentQuestionFeatureConfig.isEnabled() fun getSteps(): List = when { - isSiteNameEnabled -> listOf(INTENTS, SITE_NAME, SITE_DESIGNS, SITE_PREVIEW) - isIntentsEnabled -> listOf(INTENTS, SITE_DESIGNS, DOMAINS, SITE_PREVIEW) - else -> listOf(SITE_DESIGNS, DOMAINS, SITE_PREVIEW) + isSiteNameEnabled -> listOf(INTENTS, SITE_NAME, SITE_DESIGNS, PROGRESS, SITE_PREVIEW) + isIntentsEnabled -> listOf(INTENTS, SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW) + else -> listOf(SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/DomainsScreenListener.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/DomainsScreenListener.kt index d79672868bde..96ea55347d88 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/DomainsScreenListener.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/DomainsScreenListener.kt @@ -1,5 +1,17 @@ package org.wordpress.android.ui.sitecreation.domains +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + interface DomainsScreenListener { - fun onDomainSelected(domain: String) + fun onDomainSelected(domain: DomainModel) } + +@Parcelize +data class DomainModel( + val domainName: String, + val isFree: Boolean, + val cost: String, + val productId: Int, + val supportsPrivacy: Boolean, +) : Parcelable diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsFragment.kt index 22b0449ce705..847070e5399c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsFragment.kt @@ -4,6 +4,7 @@ import android.content.Context import android.os.Bundle import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -48,10 +49,7 @@ class SiteCreationDomainsFragment : SiteCreationBaseFormFragment() { return R.layout.site_creation_domains_screen } - @Suppress("UseCheckOrError") - override val screenTitle: String - get() = arguments?.getString(EXTRA_SCREEN_TITLE) - ?: throw IllegalStateException("Required argument screen title is missing.") + override val screenTitle get() = requireArguments().getString(EXTRA_SCREEN_TITLE).orEmpty() override fun setBindingViewStubListener(parentBinding: SiteCreationFormScreenBinding) { parentBinding.siteCreationFormContentStub.setOnInflateListener { _, inflated -> @@ -88,8 +86,8 @@ class SiteCreationDomainsFragment : SiteCreationBaseFormFragment() { searchInputWithHeader?.updateHeader(requireActivity(), uiState.headerUiState) searchInputWithHeader?.updateSearchInput(requireActivity(), uiState.searchInputUiState) updateContentUiState(uiState.contentState) - uiHelpers.updateVisibility(createSiteButtonContainer, uiState.createSiteButtonContainerVisibility) - uiHelpers.updateVisibility(createSiteButtonShadow, uiState.createSiteButtonContainerVisibility) + createSiteButtonContainer.isVisible = uiState.createSiteButtonState != null + createSiteButton.text = uiState.createSiteButtonState?.stringRes?.let(::getString) updateTitleVisibility(uiState.headerUiState == null) } }) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt index 55ec92234731..abf110b0fd2b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt @@ -29,6 +29,7 @@ import org.wordpress.android.models.networkresource.ListState.Success import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.UI_THREAD import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainSuggestionsQuery.UserQuery +import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainsUiState.CreateSiteButtonState import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainsUiState.DomainsUiContentState import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.ListItemUiState.New import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.ListItemUiState.New.DomainUiState.Cost @@ -49,7 +50,6 @@ import org.wordpress.android.util.AppLog import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig import org.wordpress.android.util.extensions.isOnSale -import org.wordpress.android.util.extensions.saleCostForDisplay import org.wordpress.android.viewmodel.SingleLiveEvent import javax.inject.Inject import javax.inject.Named @@ -89,8 +89,8 @@ class SiteCreationDomainsViewModel @Inject constructor( } } - private val _createSiteBtnClicked = SingleLiveEvent() - val createSiteBtnClicked: LiveData = _createSiteBtnClicked + private val _createSiteBtnClicked = SingleLiveEvent() + val createSiteBtnClicked: LiveData = _createSiteBtnClicked private val _clearBtnClicked = SingleLiveEvent() val clearBtnClicked = _clearBtnClicked @@ -135,7 +135,7 @@ class SiteCreationDomainsViewModel @Inject constructor( "Create site button should not be visible if a domain is not selected" } tracker.trackDomainSelected(domain.domainName, currentQuery?.value ?: "") - _createSiteBtnClicked.value = domain.domainName + _createSiteBtnClicked.value = domain } fun onClearTextBtnClicked() = _clearBtnClicked.call() @@ -225,6 +225,7 @@ class SiteCreationDomainsViewModel @Inject constructor( isFree = is_free, cost = cost.orEmpty(), productId = product_id, + supportsPrivacy = supports_privacy, ) } @@ -246,12 +247,15 @@ class SiteCreationDomainsViewModel @Inject constructor( showDivider = state.data.isNotEmpty() ), contentState = createDomainsUiContentState(query, state, emptyListMessage), - createSiteButtonContainerVisibility = getCreateSiteButtonState() + createSiteButtonState = getCreateSiteButtonState() ) } - private fun getCreateSiteButtonState(): Boolean { - return selectedDomain?.isFree ?: false + private fun getCreateSiteButtonState() = selectedDomain?.run { + when (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) { + true -> if (isFree) CreateSiteButtonState.Free else CreateSiteButtonState.Paid + else -> CreateSiteButtonState.Old + } } private fun createDomainsUiContentState( @@ -316,7 +320,7 @@ class SiteCreationDomainsViewModel @Inject constructor( domain.domainName, cost = when { domain.isFree -> Cost.Free - product.isOnSale() -> Cost.OnSale(product.saleCostForDisplay(), domain.cost) + product.isOnSale() -> Cost.OnSale(product?.combinedSaleCostDisplay.orEmpty(), domain.cost) else -> Cost.Paid(domain.cost) }, onClick = { onDomainSelected(domain) }, @@ -382,23 +386,16 @@ class SiteCreationDomainsViewModel @Inject constructor( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun onDomainSelected(domain: DomainModel) { - selectedDomain = domain.takeIf { it.isFree } + selectedDomain = domain } private fun isNonEmptyUserQuery(query: DomainSuggestionsQuery?) = query is UserQuery && query.value.isNotBlank() - data class DomainModel( - val domainName: String, - val isFree: Boolean, - val cost: String, - val productId: Int, - ) - data class DomainsUiState( val headerUiState: SiteCreationHeaderUiState?, val searchInputUiState: SiteCreationSearchInputUiState, val contentState: DomainsUiContentState = DomainsUiContentState.Initial, - val createSiteButtonContainerVisibility: Boolean + val createSiteButtonState: CreateSiteButtonState? ) { sealed class DomainsUiContentState( val emptyViewVisibility: Boolean, @@ -423,6 +420,12 @@ class SiteCreationDomainsViewModel @Inject constructor( items = items ) } + + sealed class CreateSiteButtonState(@StringRes val stringRes: Int) { + object Old : CreateSiteButtonState(R.string.site_creation_domain_finish_button) + object Free : CreateSiteButtonState(R.string.site_creation_domain_button_continue_with_subdomain) + object Paid : CreateSiteButtonState(R.string.site_creation_domain_button_purchase_domain) + } } sealed class ListItemUiState(open val type: Type) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SiteCreationPreviewFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SiteCreationPreviewFragment.kt index 785da3cb29d9..3e895c8b23e3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SiteCreationPreviewFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SiteCreationPreviewFragment.kt @@ -1,11 +1,9 @@ package org.wordpress.android.ui.sitecreation.previews -import android.animation.Animator -import android.animation.AnimatorListenerAdapter import android.animation.AnimatorSet import android.animation.ObjectAnimator import android.content.Context -import android.content.res.Configuration +import android.content.res.Configuration.ORIENTATION_LANDSCAPE import android.os.Bundle import android.text.Spannable import android.text.SpannableString @@ -15,100 +13,60 @@ import android.view.View.OnLayoutChangeListener import android.view.animation.DecelerateInterpolator import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat -import androidx.fragment.app.viewModels +import androidx.fragment.app.activityViewModels import dagger.hilt.android.AndroidEntryPoint import org.wordpress.android.R import org.wordpress.android.WordPress -import org.wordpress.android.databinding.FullscreenErrorWithRetryBinding import org.wordpress.android.databinding.SiteCreationFormScreenBinding import org.wordpress.android.databinding.SiteCreationPreviewScreenBinding import org.wordpress.android.databinding.SiteCreationPreviewScreenDefaultBinding -import org.wordpress.android.databinding.SiteCreationProgressCreatingSiteBinding -import org.wordpress.android.ui.accounts.HelpActivity +import org.wordpress.android.ui.sitecreation.SiteCreationActivity.Companion.ARG_STATE import org.wordpress.android.ui.sitecreation.SiteCreationBaseFormFragment import org.wordpress.android.ui.sitecreation.SiteCreationState -import org.wordpress.android.ui.sitecreation.misc.OnHelpClickedListener import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewData import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewContentUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenErrorUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenProgressUiState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewLoadingShimmerState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewWebErrorUiState -import org.wordpress.android.ui.sitecreation.services.SiteCreationService import org.wordpress.android.ui.utils.UiHelpers -import org.wordpress.android.util.AniUtils -import org.wordpress.android.util.AppLog -import org.wordpress.android.util.AutoForeground.ServiceEventConnection import org.wordpress.android.util.ErrorManagedWebViewClient.ErrorManagedWebViewClientListener import org.wordpress.android.util.URLFilteredWebViewClient import org.wordpress.android.util.extensions.getParcelableCompat +import org.wordpress.android.widgets.NestedWebView import javax.inject.Inject -private const val ARG_DATA = "arg_site_creation_data" private const val SLIDE_IN_ANIMATION_DURATION = 450L @AndroidEntryPoint class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), ErrorManagedWebViewClientListener { - /** - * We need to connect to the service, so the service knows when the app is in the background. The service - * automatically shows system notifications when site creation is in progress and the app is in the background. - */ - private var serviceEventConnection: ServiceEventConnection? = null - private val viewModel: SitePreviewViewModel by viewModels() - private var animatorSet: AnimatorSet? = null - private val isLandscape: Boolean - get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - @Inject internal lateinit var uiHelpers: UiHelpers - private var binding: SiteCreationPreviewScreenBinding? = null + private val isLandscape get() = resources.configuration.orientation == ORIENTATION_LANDSCAPE - @Suppress("UseCheckOrError") - override fun onAttach(context: Context) { - super.onAttach(context) - if (context !is SitePreviewScreenListener) { - throw IllegalStateException("Parent activity must implement SitePreviewScreenListener.") - } - if (context !is OnHelpClickedListener) { - throw IllegalStateException("Parent activity must implement OnHelpClickedListener.") - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - if (savedInstanceState == null) { - // we need to manually clear the SiteCreationService state so we don't for example receive sticky events - // from the previous run of the SiteCreation flow. - SiteCreationService.clearSiteCreationServiceState() - } - } + private lateinit var binding: SiteCreationPreviewScreenBinding + private val viewModel: SitePreviewViewModel by activityViewModels() - @Suppress("DEPRECATION") + @Suppress("DEPRECATION", "OVERRIDE_DEPRECATION") override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - - (requireActivity() as AppCompatActivity).supportActionBar?.hide() - - viewModel.start(requireArguments()[ARG_DATA] as SiteCreationState, savedInstanceState) + init() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + init() + } + + private fun init() { (requireActivity() as AppCompatActivity).supportActionBar?.hide() - viewModel.start(requireNotNull(arguments?.getParcelableCompat(ARG_DATA)), savedInstanceState) + viewModel.start(requireNotNull(requireArguments().getParcelableCompat(ARG_STATE))) } - override fun getContentLayout(): Int { - return R.layout.site_creation_preview_screen - } + override fun getContentLayout() = R.layout.site_creation_preview_screen - @Suppress("UseCheckOrError") - override val screenTitle: String - get() = arguments?.getString(EXTRA_SCREEN_TITLE) - ?: throw IllegalStateException("Required argument screen title is missing.") + override val screenTitle get() = requireArguments().getString(EXTRA_SCREEN_TITLE).orEmpty() override fun setBindingViewStubListener(parentBinding: SiteCreationFormScreenBinding) { parentBinding.siteCreationFormContentStub.setOnInflateListener { _, inflated -> @@ -117,109 +75,44 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), } override fun setupContent() { - binding?.siteCreationPreviewScreenDefault?.initViewModel() - binding?.siteCreationPreviewScreenDefault?.fullscreenErrorWithRetry?.initRetryButton() - binding?.siteCreationPreviewScreenDefault?.initOkButton() - binding?.siteCreationPreviewScreenDefault?.fullscreenErrorWithRetry?.initCancelWizardButton() - binding?.siteCreationPreviewScreenDefault?.fullscreenErrorWithRetry?.initContactSupportButton() + binding.siteCreationPreviewScreenDefault.run { + observeState() + observePreview(siteCreationPreviewWebViewContainer.sitePreviewWebView) + okButton.setOnClickListener { viewModel.onOkButtonClicked() } + } } - private fun SiteCreationPreviewScreenDefaultBinding.initViewModel() { - viewModel.uiState.observe(this@SiteCreationPreviewFragment, { uiState -> - uiState?.let { - when (uiState) { - is SitePreviewContentUiState -> updateContentLayout(uiState.data) - is SitePreviewWebErrorUiState -> updateContentLayout(uiState.data) - is SitePreviewLoadingShimmerState -> updateContentLayout(uiState.data) - is SitePreviewFullscreenProgressUiState -> - siteCreationProgressCreatingSite.updateLoadingLayout(uiState) - is SitePreviewFullscreenErrorUiState -> - fullscreenErrorWithRetry.updateErrorLayout(uiState) + private fun SiteCreationPreviewScreenDefaultBinding.observeState() { + viewModel.uiState.observe(this@SiteCreationPreviewFragment) { + it?.let { ui -> + when (ui) { + is SitePreviewContentUiState -> updateContentLayout(ui.data) + is SitePreviewWebErrorUiState -> updateContentLayout(ui.data) + is SitePreviewLoadingShimmerState -> updateContentLayout(ui.data, isFirstContent = true) + } + siteCreationPreviewWebViewContainer.apply { + uiHelpers.updateVisibility(sitePreviewWebView, ui.webViewVisibility) + uiHelpers.updateVisibility(sitePreviewWebError, ui.webViewErrorVisibility) + uiHelpers.updateVisibility(sitePreviewWebViewShimmerLayout, ui.shimmerVisibility) } - uiHelpers.updateVisibility( - siteCreationProgressCreatingSite.progressLayout, - uiState.fullscreenProgressLayoutVisibility - ) - - uiHelpers.updateVisibility(contentLayout, uiState.contentLayoutVisibility) - uiHelpers.updateVisibility( - siteCreationPreviewWebViewContainer.sitePreviewWebView, - uiState.webViewVisibility - ) - uiHelpers.updateVisibility( - siteCreationPreviewWebViewContainer.sitePreviewWebError, - uiState.webViewErrorVisibility - ) - uiHelpers.updateVisibility( - siteCreationPreviewWebViewContainer.sitePreviewWebViewShimmerLayout, - uiState.shimmerVisibility - ) - uiHelpers.updateVisibility( - fullscreenErrorWithRetry.errorLayout, - uiState.fullscreenErrorLayoutVisibility - ) - } - }) - - viewModel.preloadPreview.observe(this@SiteCreationPreviewFragment, { url -> - url?.let { urlString -> - siteCreationPreviewWebViewContainer.sitePreviewWebView.webViewClient = - URLFilteredWebViewClient(urlString, this@SiteCreationPreviewFragment) - siteCreationPreviewWebViewContainer.sitePreviewWebView.settings.userAgentString = - WordPress.getUserAgent() - siteCreationPreviewWebViewContainer.sitePreviewWebView.loadUrl(urlString) - } - }) - - viewModel.startCreateSiteService.observe(this@SiteCreationPreviewFragment, { startServiceData -> - startServiceData?.let { - SiteCreationService.createSite( - requireNotNull(activity), - startServiceData.previousState, - startServiceData.serviceData - ) } - }) - - initClickObservers() + } } - private fun initClickObservers() { - viewModel.onHelpClicked.observe(this, { - (requireActivity() as OnHelpClickedListener).onHelpClicked(HelpActivity.Origin.SITE_CREATION_CREATING) - }) - viewModel.onSiteCreationCompleted.observe(this, { - (requireActivity() as SitePreviewScreenListener).onSiteCreationCompleted() - }) - viewModel.onOkButtonClicked.observe(this, { createSiteState -> - createSiteState?.let { - (requireActivity() as SitePreviewScreenListener).onSitePreviewScreenDismissed(createSiteState) - } - }) - viewModel.onCancelWizardClicked.observe(this, { createSiteState -> - createSiteState?.let { - (requireActivity() as SitePreviewScreenListener).onSitePreviewScreenDismissed(createSiteState) + private fun observePreview(webView: NestedWebView) { + viewModel.preloadPreview.observe(this) { url -> + url?.let { urlString -> + webView.webViewClient = URLFilteredWebViewClient(urlString, this) + webView.settings.userAgentString = WordPress.getUserAgent() + webView.loadUrl(urlString) } - }) - } - - private fun FullscreenErrorWithRetryBinding.initRetryButton() { - errorRetry.setOnClickListener { viewModel.retry() } - } - - private fun SiteCreationPreviewScreenDefaultBinding.initOkButton() { - okButton.setOnClickListener { viewModel.onOkButtonClicked() } - } - - private fun FullscreenErrorWithRetryBinding.initCancelWizardButton() { - cancelWizardButton.setOnClickListener { viewModel.onCancelWizardClicked() } - } - - private fun FullscreenErrorWithRetryBinding.initContactSupportButton() { - contactSupport.setOnClickListener { viewModel.onHelpClicked() } + } } - private fun SiteCreationPreviewScreenDefaultBinding.updateContentLayout(sitePreviewData: SitePreviewData) { + private fun SiteCreationPreviewScreenDefaultBinding.updateContentLayout( + sitePreviewData: SitePreviewData, + isFirstContent: Boolean = false, + ) { sitePreviewData.apply { siteCreationPreviewWebViewContainer.sitePreviewWebUrlTitle.text = createSpannableUrl( requireNotNull(activity), @@ -228,69 +121,9 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), domainIndices ) } - if (contentLayout.visibility == View.GONE) { + if (isFirstContent) { animateContentTransition() - view?.announceForAccessibility( - getString(R.string.new_site_creation_preview_title) + - getString(R.string.new_site_creation_site_preview_content_description) - ) - } - } - - private fun SiteCreationProgressCreatingSiteBinding.updateLoadingLayout( - progressUiState: SitePreviewFullscreenProgressUiState - ) { - progressUiState.apply { - val newText = uiHelpers.getTextOfUiString(progressText.context, loadingTextResId) - AppLog.d(AppLog.T.MAIN, "Changing text - animation: $animate") - if (animate) { - updateLoadingTextWithFadeAnimation(newText) - } else { - progressText.text = newText - } - } - } - - private fun SiteCreationProgressCreatingSiteBinding.updateLoadingTextWithFadeAnimation(newText: CharSequence) { - val animationDuration = AniUtils.Duration.SHORT - val fadeOut = AniUtils.getFadeOutAnim( - progressTextLayout, - animationDuration, - View.VISIBLE - ) - val fadeIn = AniUtils.getFadeInAnim( - progressTextLayout, - animationDuration - ) - - // update the text when the view isn't visible - fadeIn.addListener(object : AnimatorListenerAdapter() { - override fun onAnimationStart(animation: Animator) { - progressText.text = newText - } - - override fun onAnimationEnd(animation: Animator) { - super.onAnimationEnd(animation) - animatorSet = null - } - }) - // Start the fade-in animation right after the view fades out - fadeIn.startDelay = animationDuration.toMillis(progressTextLayout.context) - - animatorSet = AnimatorSet().apply { - playSequentially(fadeOut, fadeIn) - start() - } - } - - private fun FullscreenErrorWithRetryBinding.updateErrorLayout( - errorUiStateState: SitePreviewFullscreenErrorUiState - ) { - errorUiStateState.apply { - uiHelpers.setTextOrHide(errorTitle, titleResId) - uiHelpers.setTextOrHide(errorSubtitle, subtitleResId) - uiHelpers.updateVisibility(contactSupport, errorUiStateState.showContactSupport) - uiHelpers.updateVisibility(cancelWizardButton, errorUiStateState.showCancelWizardButton) + view?.announceForAccessibility(getString(R.string.new_site_creation_site_preview_content_description)) } } @@ -326,17 +159,11 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), return spannableTitle } - override fun onWebViewPageLoaded() { - viewModel.onUrlLoaded() - } + override fun onWebViewPageLoaded() = viewModel.onUrlLoaded() - override fun onWebViewReceivedError() { - viewModel.onWebViewError() - } + override fun onWebViewReceivedError() = viewModel.onWebViewError() - override fun onHelp() { - viewModel.onHelpClicked() - } + override fun onHelp() = Unit // noop private fun SiteCreationPreviewScreenDefaultBinding.animateContentTransition() { contentLayout.addOnLayoutChangeListener( @@ -361,8 +188,7 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), contentHeight ) - // OK button should slide in if the container exists and fade in otherwise - // difference between land & portrait + // OK button slides in if the container exists else it fades in the diff between land & portrait val okAnim = if (isLandscape) { createFadeInAnimator(okButton) } else { @@ -399,41 +225,17 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(), private fun createFadeInAnimator(view: View) = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f) - override fun onResume() { - super.onResume() - serviceEventConnection = ServiceEventConnection(context, SiteCreationService::class.java, viewModel) - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - viewModel.writeToBundle(outState) - } - - override fun onPause() { - super.onPause() - serviceEventConnection?.disconnect(context, viewModel) - } - - override fun onStop() { - super.onStop() - if (animatorSet?.isRunning == true) { - animatorSet?.cancel() - } - } - companion object { const val TAG = "site_creation_preview_fragment_tag" fun newInstance( screenTitle: String, - siteCreationData: SiteCreationState - ): SiteCreationPreviewFragment { - val fragment = SiteCreationPreviewFragment() - val bundle = Bundle() - bundle.putString(EXTRA_SCREEN_TITLE, screenTitle) - bundle.putParcelable(ARG_DATA, siteCreationData) - fragment.arguments = bundle - return fragment + siteCreationState: SiteCreationState, + ) = SiteCreationPreviewFragment().apply { + arguments = Bundle().apply { + putString(EXTRA_SCREEN_TITLE, screenTitle) + putParcelable(ARG_STATE, siteCreationState) + } } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewScreenListener.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewScreenListener.kt deleted file mode 100644 index d8c4ea075b2c..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewScreenListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.wordpress.android.ui.sitecreation.previews - -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState - -interface SitePreviewScreenListener { - fun onSitePreviewScreenDismissed(createSiteState: CreateSiteState) - fun onSiteCreationCompleted() -} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModel.kt index ccd6a2370f21..a681650e1eea 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModel.kt @@ -1,8 +1,5 @@ package org.wordpress.android.ui.sitecreation.previews -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.Parcelable import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -10,110 +7,41 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import kotlinx.parcelize.Parcelize -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode -import org.wordpress.android.R import org.wordpress.android.fluxc.Dispatcher +import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Completed +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched import org.wordpress.android.ui.sitecreation.SiteCreationState -import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.INTERNET_UNAVAILABLE_ERROR -import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.UNKNOWN import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteCreationCompleted -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotCreated -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotInLocalDb import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewContentUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenErrorUiState.SitePreviewConnectionErrorUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenErrorUiState.SitePreviewGenericErrorUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenProgressUiState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewLoadingShimmerState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewWebErrorUiState import org.wordpress.android.ui.sitecreation.services.FetchWpComSiteUseCase -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceData -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.CREATE_SITE -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.FAILURE -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.IDLE -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.SUCCESS import org.wordpress.android.ui.sitecreation.usecases.isWordPressComSubDomain -import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.util.AppLog import org.wordpress.android.util.AppLog.T -import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.util.UrlUtilsWrapper -import org.wordpress.android.util.extensions.getParcelableCompat import org.wordpress.android.viewmodel.SingleLiveEvent import javax.inject.Inject import javax.inject.Named import kotlin.coroutines.CoroutineContext -const val KEY_CREATE_SITE_STATE = "CREATE_SITE_STATE" -private const val CONNECTION_ERROR_DELAY_TO_SHOW_LOADING_STATE = 1000L -private const val DELAY_TO_SHOW_WEB_VIEW_LOADING_SHIMMER = 1000L -const val LOADING_STATE_TEXT_ANIMATION_DELAY = 2000L -private const val ERROR_CONTEXT = "site_preview" - -private val loadingTexts = listOf( - UiStringRes(R.string.new_site_creation_creating_site_loading_1), - UiStringRes(R.string.new_site_creation_creating_site_loading_2), - UiStringRes(R.string.new_site_creation_creating_site_loading_3), - UiStringRes(R.string.new_site_creation_creating_site_loading_4) -) - @HiltViewModel class SitePreviewViewModel @Inject constructor( private val dispatcher: Dispatcher, private val siteStore: SiteStore, private val fetchWpComSiteUseCase: FetchWpComSiteUseCase, - private val networkUtils: NetworkUtilsWrapper, private val urlUtils: UrlUtilsWrapper, private val tracker: SiteCreationTracker, @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, @Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher ) : ViewModel(), CoroutineScope { - private val job = Job() - override val coroutineContext: CoroutineContext - get() = bgDispatcher + job - private var isStarted = false - private var webviewFullyLoadedTracked = false - private var loadingAnimationJob: Job? = null - - private lateinit var siteCreationState: SiteCreationState - private var urlWithoutScheme: String? = null - private var siteTitle: String? = null - private var lastReceivedServiceState: SiteCreationServiceState? = null - private var serviceStateForRetry: SiteCreationServiceState? = null - private var createSiteState: CreateSiteState = SiteNotCreated - - private val _uiState: MutableLiveData = MutableLiveData() - val uiState: LiveData = _uiState - - private val _preloadPreview: MutableLiveData = MutableLiveData() - val preloadPreview: LiveData = _preloadPreview - - private val _startCreateSiteService: SingleLiveEvent = SingleLiveEvent() - val startCreateSiteService: LiveData = _startCreateSiteService - - private val _onHelpClicked = SingleLiveEvent() - val onHelpClicked: LiveData = _onHelpClicked - - private val _onCancelWizardClicked = SingleLiveEvent() - val onCancelWizardClicked: LiveData = _onCancelWizardClicked - - private val _onOkButtonClicked = SingleLiveEvent() - val onOkButtonClicked: LiveData = _onOkButtonClicked - - private val _onSiteCreationCompleted = SingleLiveEvent() - val onSiteCreationCompleted: LiveData = _onSiteCreationCompleted - init { dispatcher.register(fetchWpComSiteUseCase) } @@ -122,161 +50,59 @@ class SitePreviewViewModel @Inject constructor( super.onCleared() dispatcher.unregister(fetchWpComSiteUseCase) job.cancel() - loadingAnimationJob?.cancel() } - fun writeToBundle(outState: Bundle) { - outState.putParcelable(KEY_CREATE_SITE_STATE, createSiteState) - } + private val job = Job() + override val coroutineContext: CoroutineContext + get() = bgDispatcher + job + private var isStarted = false + private var webviewFullyLoadedTracked = false - fun start(siteCreationState: SiteCreationState, savedState: Bundle?) { - if (isStarted) { - return - } - isStarted = true - this.siteCreationState = siteCreationState - urlWithoutScheme = siteCreationState.domain - siteTitle = siteCreationState.siteName + private var siteDesign: String? = null + private var urlWithoutScheme: String? = null - val restoredState = savedState?.getParcelableCompat(KEY_CREATE_SITE_STATE) + private lateinit var result: Created - init(restoredState ?: SiteNotCreated) - } + private val _uiState: MutableLiveData = MutableLiveData() + val uiState: LiveData = _uiState - private fun init(state: CreateSiteState) { - createSiteState = state - when (state) { - SiteNotCreated -> { - showFullscreenProgress() - startCreateSiteService() - } - is SiteNotInLocalDb -> { - showFullscreenProgress() - startPreLoadingWebView() - fetchNewlyCreatedSiteModel(state.remoteSiteId) - } - is SiteCreationCompleted -> { - startPreLoadingWebView(skipDelay = true) - } - } - } + private val _preloadPreview: MutableLiveData = MutableLiveData() + val preloadPreview: LiveData = _preloadPreview - private fun startCreateSiteService(previousState: SiteCreationServiceState? = null) { - if (networkUtils.isNetworkAvailable()) { - siteCreationState.apply { - // A non-null [segmentId] may invalidate the [siteDesign] selection - // https://github.com/wordpress-mobile/WordPress-Android/issues/13749 - val segmentIdentifier = if (siteDesign != null) null else segmentId - val serviceData = SiteCreationServiceData( - segmentIdentifier, - siteDesign, - urlWithoutScheme, - siteTitle - ) - _startCreateSiteService.value = SitePreviewStartServiceData(serviceData, previousState) + private val _onOkButtonClicked = SingleLiveEvent() + val onOkButtonClicked: LiveData = _onOkButtonClicked + + fun start(siteCreationState: SiteCreationState) { + if (isStarted) return else isStarted = true + require(siteCreationState.result is Created) + siteDesign = siteCreationState.siteDesign + result = siteCreationState.result + urlWithoutScheme = result.site.url + startPreLoadingWebView() + if (result is CreatedButNotFetched) { + launch { + fetchNewlyCreatedSiteModel(result.site.siteId)?.let { + result = Completed(it) + } } - } else { - showFullscreenErrorWithDelay() } } - fun retry() { - showFullscreenProgress() - startCreateSiteService(serviceStateForRetry) - } - - fun onHelpClicked() { - _onHelpClicked.call() - } - - fun onCancelWizardClicked() { - _onCancelWizardClicked.value = createSiteState - } - fun onOkButtonClicked() { tracker.trackPreviewOkButtonTapped() - _onOkButtonClicked.value = createSiteState - } - - private fun showFullscreenErrorWithDelay() { - showFullscreenProgress() - launch(mainDispatcher) { - // We show the loading indicator for a bit so the user has some feedback when they press retry - delay(CONNECTION_ERROR_DELAY_TO_SHOW_LOADING_STATE) - tracker.trackErrorShown(ERROR_CONTEXT, INTERNET_UNAVAILABLE_ERROR) - updateUiState(SitePreviewConnectionErrorUiState) - } + _onOkButtonClicked.postValue(result) } - /** - * The service automatically shows system notifications when site creation is in progress and the app is in - * the background. We need to connect to the `AutoForeground` service from the View(Fragment), as only the View - * knows when the app is in the background. Required parameter for `ServiceEventConnection` is also - * the observer/listener of the `SiteCreationServiceState` (VM in our case), therefore we can't simply register - * to the EventBus from the ViewModel and we have to use `sticky` events instead. - */ - @Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true) - @Suppress("unused") - fun onSiteCreationServiceStateUpdated(event: SiteCreationServiceState) { - if (lastReceivedServiceState == event) return // filter out events which we've already received - lastReceivedServiceState = event - when (event.step) { - IDLE, CREATE_SITE -> { - } // do nothing - SUCCESS -> { - val remoteSiteId = (event.payload as Pair<*, *>).first as Long - urlWithoutScheme = urlUtils.removeScheme(event.payload.second as String).trimEnd('/') - createSiteState = SiteNotInLocalDb(remoteSiteId, !siteTitle.isNullOrBlank()) - startPreLoadingWebView() - fetchNewlyCreatedSiteModel(remoteSiteId) - _onSiteCreationCompleted.asyncCall() - } - FAILURE -> { - serviceStateForRetry = event.payload as SiteCreationServiceState - tracker.trackErrorShown( - ERROR_CONTEXT, - UNKNOWN, - "SiteCreation service failed" - ) - updateUiStateAsync(SitePreviewGenericErrorUiState) - } - } - } - - /** - * Fetch newly created site model - supports retry with linear backoff. - */ - private fun fetchNewlyCreatedSiteModel(remoteSiteId: Long) { + private fun startPreLoadingWebView() { + tracker.trackPreviewLoading(siteDesign) launch { - val onSiteFetched = fetchWpComSiteUseCase.fetchSiteWithRetry(remoteSiteId) - createSiteState = if (!onSiteFetched.isError) { - val siteBySiteId = requireNotNull(siteStore.getSiteBySiteId(remoteSiteId)) { - "Site successfully fetched but has not been found in the local db." - } - CreateSiteState.SiteCreationCompleted(siteBySiteId.id, !siteTitle.isNullOrBlank()) - } else { - SiteNotInLocalDb(remoteSiteId, !siteTitle.isNullOrBlank()) - } - } - } - - private fun startPreLoadingWebView(skipDelay: Boolean = false) { - tracker.trackPreviewLoading(siteCreationState.siteDesign) - launch { - if (!skipDelay) { - /** - * Keep showing the full screen loading screen for 1 more second or until the webview is loaded - * whichever happens first. This will give us some more time to fetch the newly created site. - */ - delay(DELAY_TO_SHOW_WEB_VIEW_LOADING_SHIMMER) - } /** * If the webview is still not loaded after some delay, we'll show the loading shimmer animation instead * of the full screen progress, so the user is not blocked for taking actions. */ withContext(mainDispatcher) { if (uiState.value !is SitePreviewContentUiState) { - tracker.trackPreviewWebviewShown(siteCreationState.siteDesign) + tracker.trackPreviewWebviewShown(siteDesign) updateUiState(SitePreviewLoadingShimmerState(createSitePreviewData())) } } @@ -292,10 +118,24 @@ class SitePreviewViewModel @Inject constructor( } } + /** + * Fetch newly created site model - supports retry with linear backoff. + */ + private suspend fun fetchNewlyCreatedSiteModel(remoteSiteId: Long): SiteModel? { + val onSiteFetched = fetchWpComSiteUseCase.fetchSiteWithRetry(remoteSiteId) + return if (!onSiteFetched.isError) { + return requireNotNull(siteStore.getSiteBySiteId(remoteSiteId)) { + "Site successfully fetched but has not been found in the local db." + } + } else { + null + } + } + fun onUrlLoaded() { if (!webviewFullyLoadedTracked) { webviewFullyLoadedTracked = true - tracker.trackPreviewWebviewFullyLoaded(siteCreationState.siteDesign) + tracker.trackPreviewWebviewFullyLoaded(siteDesign) } /** * Update the ui state if the loading or error screen is being shown. @@ -316,11 +156,8 @@ class SitePreviewViewModel @Inject constructor( val url = urlWithoutScheme ?: "" val subDomain = urlUtils.extractSubDomain(url) val fullUrl = urlUtils.addUrlSchemeIfNeeded(url, true) - val subDomainIndices: Pair = Pair(0, subDomain.length) - val domainIndices: Pair = Pair( - Math.min(subDomainIndices.second, url.length), - url.length - ) + val subDomainIndices = 0 to subDomain.length + val domainIndices = subDomainIndices.second.coerceAtMost(url.length) to url.length return SitePreviewData( fullUrl, url, @@ -329,84 +166,28 @@ class SitePreviewViewModel @Inject constructor( ) } - private fun showFullscreenProgress() { - loadingAnimationJob?.cancel() - loadingAnimationJob = launch(mainDispatcher) { - var i = 0 - val listSize = loadingTexts.size - while (isActive) { - updateUiState( - SitePreviewFullscreenProgressUiState( - animate = i != 0, // the first text should appear without an animation - loadingTextResId = loadingTexts[i++ % listSize] - ) - ) - delay(LOADING_STATE_TEXT_ANIMATION_DELAY) - } - } - } - private fun updateUiState(uiState: SitePreviewUiState) { - if (uiState !is SitePreviewFullscreenProgressUiState) { - loadingAnimationJob?.cancel() - } _uiState.value = uiState } - private fun updateUiStateAsync(uiState: SitePreviewUiState) { - if (uiState !is SitePreviewFullscreenProgressUiState) { - loadingAnimationJob?.cancel() - } - _uiState.postValue(uiState) - } - sealed class SitePreviewUiState( - val fullscreenProgressLayoutVisibility: Boolean = false, - val contentLayoutVisibility: Boolean = false, val webViewVisibility: Boolean = false, val webViewErrorVisibility: Boolean = false, val shimmerVisibility: Boolean = false, - val fullscreenErrorLayoutVisibility: Boolean = false ) { data class SitePreviewContentUiState(val data: SitePreviewData) : SitePreviewUiState( - contentLayoutVisibility = true, webViewVisibility = true, webViewErrorVisibility = false ) data class SitePreviewWebErrorUiState(val data: SitePreviewData) : SitePreviewUiState( - contentLayoutVisibility = true, webViewVisibility = false, webViewErrorVisibility = true ) data class SitePreviewLoadingShimmerState(val data: SitePreviewData) : SitePreviewUiState( - contentLayoutVisibility = true, shimmerVisibility = true ) - - data class SitePreviewFullscreenProgressUiState(val loadingTextResId: UiString, val animate: Boolean) : - SitePreviewUiState(fullscreenProgressLayoutVisibility = true) - - sealed class SitePreviewFullscreenErrorUiState constructor( - val titleResId: Int, - val subtitleResId: Int? = null, - val showContactSupport: Boolean = false, - val showCancelWizardButton: Boolean = true - ) : SitePreviewUiState( - fullscreenErrorLayoutVisibility = true - ) { - object SitePreviewGenericErrorUiState : - SitePreviewFullscreenErrorUiState( - R.string.site_creation_error_generic_title, - R.string.site_creation_error_generic_subtitle, - showContactSupport = true - ) - - object SitePreviewConnectionErrorUiState : SitePreviewFullscreenErrorUiState( - R.string.no_network_message - ) - } } data class SitePreviewData( @@ -415,32 +196,4 @@ class SitePreviewViewModel @Inject constructor( val domainIndices: Pair, val subDomainIndices: Pair ) - - data class SitePreviewStartServiceData( - val serviceData: SiteCreationServiceData, - val previousState: SiteCreationServiceState? - ) - - @SuppressLint("ParcelCreator") - sealed class CreateSiteState : Parcelable { - /** - * CreateSite request haven't finished yet or failed. - */ - @Parcelize - object SiteNotCreated : CreateSiteState() - - /** - * FetchSite request haven't finished yet or failed. - * Since we fetch the site without user awareness in background, the user may potentially leave the screen - * before the request is finished. - */ - @Parcelize - data class SiteNotInLocalDb(val remoteSiteId: Long, val isSiteTitleTaskComplete: Boolean) : CreateSiteState() - - /** - * The site has been successfully created and stored into local db. - */ - @Parcelize - data class SiteCreationCompleted(val localSiteId: Int, val isSiteTitleTaskComplete: Boolean) : CreateSiteState() - } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressFragment.kt new file mode 100644 index 000000000000..b898b4c35dba --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressFragment.kt @@ -0,0 +1,193 @@ +package org.wordpress.android.ui.sitecreation.progress + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.AnimatorSet +import android.content.Context +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint +import org.wordpress.android.R +import org.wordpress.android.databinding.FullscreenErrorWithRetryBinding +import org.wordpress.android.databinding.SiteCreationProgressCreatingSiteBinding +import org.wordpress.android.databinding.SiteCreationProgressScreenBinding +import org.wordpress.android.ui.accounts.HelpActivity +import org.wordpress.android.ui.sitecreation.SiteCreationActivity.Companion.ARG_STATE +import org.wordpress.android.ui.sitecreation.SiteCreationState +import org.wordpress.android.ui.sitecreation.misc.OnHelpClickedListener +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Loading +import org.wordpress.android.ui.sitecreation.services.SiteCreationService +import org.wordpress.android.ui.utils.UiHelpers +import org.wordpress.android.util.AniUtils +import org.wordpress.android.util.AppLog +import org.wordpress.android.util.AutoForeground.ServiceEventConnection +import org.wordpress.android.util.extensions.getParcelableCompat +import javax.inject.Inject + +@AndroidEntryPoint +class SiteCreationProgressFragment : Fragment(R.layout.site_creation_progress_screen) { + @Inject + internal lateinit var uiHelpers: UiHelpers + + /** + * We need to connect to the service, so the service knows when the app is in the background. The service + * automatically shows system notifications when site creation is in progress and the app is in the background. + */ + private var serviceEventConnection: ServiceEventConnection? = null + private var animatorSet: AnimatorSet? = null + + private lateinit var binding: SiteCreationProgressScreenBinding + private val viewModel: SiteCreationProgressViewModel by activityViewModels() + + override fun onAttach(context: Context) { + super.onAttach(context) + check(context is OnHelpClickedListener) { "Parent activity must implement OnHelpClickedListener." } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (savedInstanceState == null) { + // we need to manually clear the service state to avoid sticky events from the previous SiteCreation flow. + SiteCreationService.clearSiteCreationServiceState() + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding = SiteCreationProgressScreenBinding.bind(view).apply { + observeState() + observeHelpClicks(requireActivity() as OnHelpClickedListener) + observeSiteCreationService() + fullscreenErrorWithRetry.setOnClickListeners() + } + + (requireActivity() as AppCompatActivity).supportActionBar?.hide() + + viewModel.start(requireNotNull(requireArguments().getParcelableCompat(ARG_STATE))) + } + + private fun SiteCreationProgressScreenBinding.observeState() { + viewModel.uiState.observe(viewLifecycleOwner) { uiState -> + uiState?.run { + when (val ui = this@run) { + is Loading -> siteCreationProgressCreatingSite.updateLoadingLayout(ui) + is Error -> fullscreenErrorWithRetry.updateErrorLayout(ui) + } + siteCreationProgressCreatingSite.progressLayout.isVisible = progressLayoutVisibility + fullscreenErrorWithRetry.errorLayout.isVisible = errorLayoutVisibility + } + } + } + + private fun observeSiteCreationService() { + viewModel.startCreateSiteService.observe(viewLifecycleOwner) { startServiceData -> + startServiceData?.let { + SiteCreationService.createSite(requireNotNull(activity), it.previousState, it.serviceData) + } + } + viewModel.onFreeSiteCreated.observe(viewLifecycleOwner) { + view?.announceForAccessibility(getString(R.string.new_site_creation_preview_title)) + } + } + + private fun observeHelpClicks(listener: OnHelpClickedListener) { + viewModel.onHelpClicked.observe(viewLifecycleOwner) { + listener.onHelpClicked(HelpActivity.Origin.SITE_CREATION_CREATING) + } + } + + private fun FullscreenErrorWithRetryBinding.setOnClickListeners() { + errorRetry.setOnClickListener { viewModel.retry() } + cancelWizardButton.setOnClickListener { viewModel.onCancelWizardClicked() } + contactSupport.setOnClickListener { viewModel.onHelpClicked() } + } + + private fun FullscreenErrorWithRetryBinding.updateErrorLayout(errorUiState: Error) { + errorUiState.run { + uiHelpers.setTextOrHide(errorTitle, titleResId) + uiHelpers.setTextOrHide(errorSubtitle, subtitleResId) + uiHelpers.updateVisibility(contactSupport, errorUiState.showContactSupport) + uiHelpers.updateVisibility(cancelWizardButton, errorUiState.showCancelWizardButton) + } + } + + private fun SiteCreationProgressCreatingSiteBinding.updateLoadingLayout( + progressUiState: Loading + ) { + progressUiState.apply { + val newText = uiHelpers.getTextOfUiString(progressText.context, loadingTextResId) + AppLog.d(AppLog.T.MAIN, "Changing text - animation: $animate") + if (animate) { + updateLoadingTextWithFadeAnimation(newText) + } else { + progressText.text = newText + } + } + } + + private fun SiteCreationProgressCreatingSiteBinding.updateLoadingTextWithFadeAnimation(newText: CharSequence) { + val animationDuration = AniUtils.Duration.SHORT + val fadeOut = AniUtils.getFadeOutAnim( + progressTextLayout, + animationDuration, + View.VISIBLE + ) + val fadeIn = AniUtils.getFadeInAnim( + progressTextLayout, + animationDuration + ) + + // update the text when the view isn't visible + fadeIn.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationStart(animation: Animator) { + progressText.text = newText + } + + override fun onAnimationEnd(animation: Animator) { + super.onAnimationEnd(animation) + animatorSet = null + } + }) + // Start the fade-in animation right after the view fades out + fadeIn.startDelay = animationDuration.toMillis(progressTextLayout.context) + + animatorSet = AnimatorSet().apply { + playSequentially(fadeOut, fadeIn) + start() + } + } + + override fun onResume() { + super.onResume() + serviceEventConnection = ServiceEventConnection(context, SiteCreationService::class.java, viewModel) + } + + override fun onPause() { + super.onPause() + serviceEventConnection?.disconnect(context, viewModel) + } + + override fun onStop() { + super.onStop() + if (animatorSet?.isRunning == true) { + animatorSet?.cancel() + } + } + + companion object { + const val TAG = "site_creation_progress_fragment_tag" + + fun newInstance(siteCreationState: SiteCreationState) = SiteCreationProgressFragment() + .apply { + arguments = Bundle().apply { + putParcelable(ARG_STATE, siteCreationState) + } + } + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt new file mode 100644 index 000000000000..879b278d262b --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt @@ -0,0 +1,261 @@ +package org.wordpress.android.ui.sitecreation.progress + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode +import org.wordpress.android.R +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewActivity.OpenCheckout.CheckoutDetails +import org.wordpress.android.ui.domains.usecases.CreateCartUseCase +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched +import org.wordpress.android.ui.sitecreation.SiteCreationState +import org.wordpress.android.ui.sitecreation.domains.DomainModel +import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.INTERNET_UNAVAILABLE_ERROR +import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.UNKNOWN +import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.ConnectionError +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.GenericError +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Loading +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceData +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.CREATE_SITE +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.FAILURE +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.IDLE +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.SUCCESS +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.ui.utils.UiString.UiStringRes +import org.wordpress.android.util.AppLog +import org.wordpress.android.util.NetworkUtilsWrapper +import org.wordpress.android.viewmodel.ScopedViewModel +import org.wordpress.android.viewmodel.SingleLiveEvent +import javax.inject.Inject +import javax.inject.Named + +private const val CONNECTION_ERROR_DELAY_TO_SHOW_LOADING_STATE = 1000L +const val LOADING_STATE_TEXT_ANIMATION_DELAY = 2000L +private const val ERROR_CONTEXT = "site_preview" +private val LOG_TAG = AppLog.T.SITE_CREATION + +private val loadingTexts = listOf( + UiStringRes(R.string.new_site_creation_creating_site_loading_1), + UiStringRes(R.string.new_site_creation_creating_site_loading_2), + UiStringRes(R.string.new_site_creation_creating_site_loading_3), + UiStringRes(R.string.new_site_creation_creating_site_loading_4) +) + +@HiltViewModel +class SiteCreationProgressViewModel @Inject constructor( + private val networkUtils: NetworkUtilsWrapper, + private val tracker: SiteCreationTracker, + private val createCartUseCase: CreateCartUseCase, + @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, +) : ScopedViewModel(mainDispatcher) { + private var loadingAnimationJob: Job? = null + + private lateinit var siteCreationState: SiteCreationState + private lateinit var domain: DomainModel + + private var lastReceivedServiceState: SiteCreationServiceState? = null + private var serviceStateForRetry: SiteCreationServiceState? = null + + private val _uiState: MutableLiveData = MutableLiveData() + val uiState: LiveData = _uiState + + private val _startCreateSiteService: SingleLiveEvent = SingleLiveEvent() + val startCreateSiteService: LiveData = _startCreateSiteService + + private val _onHelpClicked = SingleLiveEvent() + val onHelpClicked: LiveData = _onHelpClicked + + private val _onCancelWizardClicked = SingleLiveEvent() + val onCancelWizardClicked: LiveData = _onCancelWizardClicked + + private val _onFreeSiteCreated = SingleLiveEvent() + val onFreeSiteCreated: LiveData = _onFreeSiteCreated + + private val _onCartCreated = SingleLiveEvent() + val onCartCreated: LiveData = _onCartCreated + + override fun onCleared() { + super.onCleared() + loadingAnimationJob?.cancel() + createCartUseCase.clear() + } + + fun start(siteCreationState: SiteCreationState) { + if (siteCreationState.result is CreatedButNotFetched.InCart) { + // reuse the previously blog when returning with the same domain + if (siteCreationState.domain == this.siteCreationState.domain) { + createCart(siteCreationState.result.site) + return + } + } + this.siteCreationState = siteCreationState + domain = requireNotNull(siteCreationState.domain) { "domain required to create a site" } + + runLoadingAnimationUi() + startCreateSiteService() + } + + private fun startCreateSiteService(previousState: SiteCreationServiceState? = null) { + if (networkUtils.isNetworkAvailable()) { + siteCreationState.let { state -> + // A non-null [segmentId] may invalidate the [siteDesign] selection + // https://github.com/wordpress-mobile/WordPress-Android/issues/13749 + val segmentIdentifier = state.segmentId.takeIf { state.siteDesign != null } + val serviceData = SiteCreationServiceData( + segmentIdentifier, + state.siteDesign, + domain.domainName, + state.siteName, + domain.isFree, + ) + _startCreateSiteService.value = StartServiceData(serviceData, previousState) + } + } else { + showFullscreenErrorWithDelay() + } + } + + fun retry() { + runLoadingAnimationUi() + startCreateSiteService(serviceStateForRetry) + } + + fun onHelpClicked() = _onHelpClicked.call() + + fun onCancelWizardClicked() = _onCancelWizardClicked.call() + + private fun showFullscreenErrorWithDelay() { + runLoadingAnimationUi() + launch { + // We show the loading indicator for a bit so the user has some feedback when they press retry + delay(CONNECTION_ERROR_DELAY_TO_SHOW_LOADING_STATE) + tracker.trackErrorShown(ERROR_CONTEXT, INTERNET_UNAVAILABLE_ERROR) + updateUiState(ConnectionError) + } + } + + /** + * The service automatically shows system notifications when site creation is in progress and the app is in + * the background. We need to connect to the `AutoForeground` service from the View(Fragment), as only the View + * knows when the app is in the background. Required parameter for `ServiceEventConnection` is also + * the observer/listener of the `SiteCreationServiceState` (VM in our case), therefore we can't simply register + * to the EventBus from the ViewModel and we have to use `sticky` events instead. + */ + @Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true) + @Suppress("unused") + fun onSiteCreationServiceStateUpdated(event: SiteCreationServiceState) { + if (lastReceivedServiceState == event) return // filter out events which we've already received + lastReceivedServiceState = event + when (event.step) { + IDLE, CREATE_SITE -> Unit + SUCCESS -> { + val site = mapPayloadToSiteModel(event.payload) + if (domain.isFree) { + _onFreeSiteCreated.postValue(site) + } else { + createCart(site) + } + } + FAILURE -> { + serviceStateForRetry = event.payload as SiteCreationServiceState + tracker.trackErrorShown( + ERROR_CONTEXT, + UNKNOWN, + "SiteCreation service failed" + ) + updateUiStateAsync(GenericError) + } + } + } + + private fun mapPayloadToSiteModel(payload: Any?): SiteModel { + require(payload is Pair<*, *>) { "Expected Pair in Payload, got: $payload" } + val (blogId, blogUrl) = payload + require(blogId is Long) { "Expected the 1st element in the Payload Pair to be a Long, got: $blogId" } + require(blogUrl is String) { "Expected the 2nd element in the Payload Pair to be a Long, got: $blogUrl" } + return SiteModel().apply { siteId = blogId; url = blogUrl } + } + + private fun createCart(site: SiteModel) = launch { + AppLog.d(LOG_TAG, "Creating cart: $domain") + + val event = createCartUseCase.execute( + site, + domain.productId, + domain.domainName, + domain.supportsPrivacy, + false, + ) + + if (event.isError) { + AppLog.e(LOG_TAG, "Failed cart creation: ${event.error.message}") + updateUiStateAsync(GenericError) + } else { + AppLog.d(LOG_TAG, "Successful cart creation: ${event.cartDetails}") + _onCartCreated.postValue(CheckoutDetails(site, domain.domainName)) + } + } + + private fun runLoadingAnimationUi() { + loadingAnimationJob?.cancel() + loadingAnimationJob = launch { + loadingTexts.forEachIndexed { i, uiString -> + updateUiState( + Loading( + animate = i != 0, // the first text should appear without an animation + loadingTextResId = uiString + ) + ) + delay(LOADING_STATE_TEXT_ANIMATION_DELAY) + } + } + } + + private fun updateUiState(uiState: SiteProgressUiState) { + if (uiState !is Loading) loadingAnimationJob?.cancel() + _uiState.value = uiState + } + + private fun updateUiStateAsync(uiState: SiteProgressUiState) { + if (uiState !is Loading) loadingAnimationJob?.cancel() + _uiState.postValue(uiState) + } + + sealed class SiteProgressUiState( + val progressLayoutVisibility: Boolean = false, + val errorLayoutVisibility: Boolean = false + ) { + data class Loading(val loadingTextResId: UiString, val animate: Boolean) : + SiteProgressUiState(progressLayoutVisibility = true) + + sealed class Error constructor( + val titleResId: Int, + val subtitleResId: Int? = null, + val showContactSupport: Boolean = false, + val showCancelWizardButton: Boolean = true + ) : SiteProgressUiState(errorLayoutVisibility = true) { + object GenericError : Error( + R.string.site_creation_error_generic_title, + R.string.site_creation_error_generic_subtitle, + showContactSupport = true + ) + + object ConnectionError : Error( + R.string.no_network_message + ) + } + } + + data class StartServiceData( + val serviceData: SiteCreationServiceData, + val previousState: SiteCreationServiceState? + ) +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceData.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceData.kt index 14f32fa688e5..7df837d1e770 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceData.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceData.kt @@ -10,5 +10,6 @@ data class SiteCreationServiceData( val segmentId: Long?, val siteDesign: String?, val domain: String?, - val title: String? + val title: String?, + val isFree: Boolean, ) : Parcelable diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManager.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManager.kt index 799013410b11..86a62720f401 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManager.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManager.kt @@ -105,7 +105,7 @@ class SiteCreationServiceManager @Inject constructor( launch { AppLog.i( T.SITE_CREATION, - "Dispatching Create Site Action, SiteName: ${siteData.domain}" + "Dispatching Create Site Action, SiteName: ${siteData.domain}, isFree: ${siteData.isFree}" ) val createSiteEvent: OnNewSiteCreated try { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/usecases/CreateSiteUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/usecases/CreateSiteUseCase.kt index 5ad93e6f89a0..1e190e2a4c5e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/usecases/CreateSiteUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/usecases/CreateSiteUseCase.kt @@ -60,7 +60,8 @@ class CreateSiteUseCase @Inject constructor( siteVisibility, siteData.segmentId, siteData.siteDesign, - dryRun + dryRun, + findAvailableUrl = if (siteData.isFree) null else true ) continuation = cont dispatcher.dispatch(SiteActionBuilder.newCreateNewSiteAction(newSitePayload)) diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/BloggingPromptsSocialFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/BloggingPromptsSocialFeatureConfig.kt index 8cdb7ca9709a..b835550fba88 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/config/BloggingPromptsSocialFeatureConfig.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/config/BloggingPromptsSocialFeatureConfig.kt @@ -1,14 +1,17 @@ package org.wordpress.android.util.config import org.wordpress.android.BuildConfig -import org.wordpress.android.annotation.FeatureInDevelopment +import org.wordpress.android.annotation.Feature import javax.inject.Inject -@FeatureInDevelopment +private const val BLOGGING_PROMPTS_SOCIAL_REMOTE_FIELD = "blogging_prompts_social_enabled" + +@Feature(BLOGGING_PROMPTS_SOCIAL_REMOTE_FIELD, true) class BloggingPromptsSocialFeatureConfig @Inject constructor(appConfig: AppConfig) : FeatureConfig( appConfig, BuildConfig.BLOGGING_PROMPTS_SOCIAL, + BLOGGING_PROMPTS_SOCIAL_REMOTE_FIELD, ) { override fun isEnabled(): Boolean { return super.isEnabled() && BuildConfig.IS_JETPACK_APP diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/ProductExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/ProductExtensions.kt index ab8fd89691ca..39861b80ed88 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/extensions/ProductExtensions.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/extensions/ProductExtensions.kt @@ -1,8 +1,5 @@ package org.wordpress.android.util.extensions import org.wordpress.android.fluxc.model.products.Product -import java.util.Currency fun Product?.isOnSale(): Boolean = this?.saleCost?.let { it > 0.0 } == true -fun Product?.saleCostForDisplay() = - this?.run { Currency.getInstance(currencyCode).symbol + "%.2f".format(saleCost) } ?: "" diff --git a/WordPress/src/main/res/layout-land/site_creation_preview_screen_default.xml b/WordPress/src/main/res/layout-land/site_creation_preview_screen_default.xml index 58d67c08010f..a4417aff34b3 100644 --- a/WordPress/src/main/res/layout-land/site_creation_preview_screen_default.xml +++ b/WordPress/src/main/res/layout-land/site_creation_preview_screen_default.xml @@ -1,61 +1,46 @@ - - - - - - - - - - - - + + - + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/margin_extra_large" + android:text="@string/dialog_button_ok" + tools:ignore="InconsistentLayout" /> + + + diff --git a/WordPress/src/main/res/layout/site_creation_preview_screen_default.xml b/WordPress/src/main/res/layout/site_creation_preview_screen_default.xml index 987ec9ebd96b..97be321cc9cd 100644 --- a/WordPress/src/main/res/layout/site_creation_preview_screen_default.xml +++ b/WordPress/src/main/res/layout/site_creation_preview_screen_default.xml @@ -2,66 +2,51 @@ + android:id="@+id/site_creation_preview_header_item" + layout="@layout/site_creation_preview_header_item" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_marginBottom="@dimen/margin_extra_medium_large" + android:layout_marginEnd="@dimen/margin_large" + android:layout_marginStart="@dimen/margin_large" + android:layout_marginTop="@dimen/margin_extra_medium_large" /> - - - - + android:layout_height="match_parent" + android:layout_above="@+id/sitePreviewOkButtonContainer" + android:layout_below="@id/site_creation_preview_header_item" + android:layout_marginBottom="@dimen/negative_margin_medium" + android:layout_marginLeft="@dimen/site_creation_preview_web_view_side_margin" + android:layout_marginRight="@dimen/site_creation_preview_web_view_side_margin" /> - + - - - - - + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginEnd="@dimen/margin_extra_large" + android:layout_marginStart="@dimen/margin_extra_large" + android:text="@string/dialog_button_ok" /> + diff --git a/WordPress/src/main/res/layout/site_creation_progress_screen.xml b/WordPress/src/main/res/layout/site_creation_progress_screen.xml new file mode 100644 index 000000000000..99b7e28edcc5 --- /dev/null +++ b/WordPress/src/main/res/layout/site_creation_progress_screen.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/WordPress/src/main/res/values-de/strings.xml b/WordPress/src/main/res/values-de/strings.xml index bed5e668ba17..fdbb8a2122ba 100644 --- a/WordPress/src/main/res/values-de/strings.xml +++ b/WordPress/src/main/res/values-de/strings.xml @@ -12,8 +12,8 @@ Language: de <b>%1$s</b> benutzt individuelle Jetpack-Plugins, die von der WordPress-App nicht unterstützt werden. <b>%1$s</b> benutzt das <b>%2$s</b> Plugin, welches nicht von der WordPress-App unterstützt wird. Auf manche deiner Websites kann nicht zugegriffen werden - Auf eine deiner Websites kann nicht zugegriffen werden Bitte wechsle zu der Jetpack-App, wo wir dich durch die Anbindung des vollständigen Jetpack-Plugins führen, damit diese Website mit der App benutzt werden kann. + Auf eine deiner Websites kann nicht zugegriffen werden Zur Jetpack-App wechseln %1$s verwendet %2$s, das noch nicht alle Funktionen der App unterstützt.\n\nBitte installiere das %3$s, um die App mit dieser Website zu verwenden. Diese Website @@ -37,34 +37,34 @@ Language: de Diese Seite mit Blaze bewerben Diesen Beitrag mit Blaze bewerben Verfolge die Performance, starte und beende Blaze jederzeit. + Hilfe + Protokolle + Hilfe Deine Inhalte werden auf Millionen von WordPress- und Tumblr-Websites angezeigt. Bewirb innerhalb von Minuten und für lediglich ein paar Dollar pro Tag jeden beliebigen Beitrag und jede Seite. Leite mit Blaze mehr Traffic auf deine Website - Blaze Diese Domain ist bereits registriert Angebot Empfohlen Beste Alternative %s/Jahr - Hilfe In unseren FAQ findest du Antworten auf häufige Fragen, die du dir vielleicht auch stellst. Danke für deinen Wechsel zur Jetpack-App! - Protokolle - Tickets Kostenlos - Hilfe + Tickets + Blaze Block-Menü Ausblenden - Präsentiere deine Werke auf Millionen von Websites. - Bewirb deine Inhalte mit Blaze Schließen Support kontaktieren Vollständiges Plugin installieren - Geschäftsbedingungen Mit der Einrichtung von Jetpack erhalten wir deine Zustimmung zu unseren + Präsentiere deine Werke auf Millionen von Websites. + Bewirb deine Inhalte mit Blaze + Geschäftsbedingungen + das %1$s-Plugin vollständige Jetpack-Plugin individuelle Jetpack-Plugins - das %1$s-Plugin %1$s verwendet %2$s, das noch nicht alle Funktionen der App unterstützt.\n\nBitte installiere %3$s, um die App mit dieser Website zu verwenden. Bitte installiere das vollständige Jetpack-Plugin Es ist nur eine Website verfügbar, du kannst deine Haupt-Website also nicht ändern. @@ -73,64 +73,64 @@ Language: de Jetpack kann zurzeit nicht installiert werden. Es ist ein Problem aufgetreten Fehler-Icon - Diese Website kann jetzt mit der App verwendet werden. Jetpack installiert Jetpack wird auf deiner Website installiert. Dieser Vorgang kann einige Minuten dauern. Jetpack wird installiert Weiter Deine Website-Anmeldedaten werden nicht gespeichert und werden nur verwendet, um Jetpack zu installieren. Jetpack installieren - Jetpack-Icon Mit Blaze bewerben + Diese Website kann jetzt mit der App verwendet werden. + Jetpack-Icon Entfalte das volle Potenzial deiner Website. Erhalte Statistiken, Benachrichtigungen und vieles mehr mit Jetpack. Deine Website hat das Jetpack-Plugin - Die Jetpack-Mobil-App wurde entwickelt, um mit dem Jetpack-Plugin zusammenzuarbeiten. Wechsle jetzt, um u. a. Zugang zu Statistiken, Benachrichtigungen und dem Reader zu erhalten. - Erhalte Benachrichtigungen über neue Kommentare, Likes, Aufrufe und vieles mehr. Suche deine Lieblingswebsites und -communities, folge ihnen und teile deine Inhalte. Beobachte dank hilfreicher Einsichten und umfassender Statistiken, wie dein Traffic wächst. + Die Jetpack-Mobil-App wurde entwickelt, um mit dem Jetpack-Plugin zusammenzuarbeiten. Wechsle jetzt, um u. a. Zugang zu Statistiken, Benachrichtigungen und dem Reader zu erhalten. + Erhalte Benachrichtigungen über neue Kommentare, Likes, Aufrufe und vieles mehr. Statistiken & Einsichten Mit Jetpack kannst du mehr aus deiner WordPress-Website herausholen. Der Wechsel ist kostenlos und dauert nur eine Minute. Gib WordPress einen Schub mit Jetpack - Unter „Meine Website > Einstellungen > Bloggen“ kannst du jederzeit Einstellungen für Blog-Schreibanregungen und -Erinnerungen vornehmen Die Benachrichtigung beinhaltet ein Wort oder einen kurzen Satz zur Inspiration - Wechsle zu den <b>Website-Einstellungen</b>, um sie wieder zu aktivieren Blog-Schreibanregungen ausgeblendet + Unter „Meine Website > Einstellungen > Bloggen“ kannst du jederzeit Einstellungen für Blog-Schreibanregungen und -Erinnerungen vornehmen + Wechsle zu den <b>Website-Einstellungen</b>, um sie wieder zu aktivieren Schreibanregungen ausschalten Erhalte Hilfe von unserer Gruppe Freiwilliger. Community-Foren Blog-Erinnerungen Schreibanregungen anzeigen Bloggen - Bitte installiere Google Play Store, um die Jetpack-App zu erhalten - Später erledigen Zu Jetpack wechseln + Später erledigen + Bitte installiere Google Play Store, um die Jetpack-App zu erhalten Statistiken, der Reader, Benachrichtigungen und weitere von Jetpack unterstützte Funktionen wurden aus der WordPress-App entfernt. Jetpack-Funktionen wurden verschoben. %1$s werden in %2$s verschoben %1$s wird in %2$s verschoben %1$s werden demnächst verschoben %1$s wird demnächst verschoben - Jetpack-App sichern - Alle Antworten anzeigen - %1$s niedriger als in den vorherigen 7 Tagen - %1$s höher als in den vorherigen 7 Tagen - Deine Besucherzahlen in den letzten 7 Tagen sind %1$s niedriger als in den vorherigen 7 Tagen. - Deine Besucherzahlen in den letzten 7 Tagen sind %1$s höher als in den vorherigen 7 Tagen. - Deine Aufrufe in den letzten 7 Tagen sind %1$s niedriger als die vorherigen 7 Tage. - Deine Aufrufe in den letzten 7 Tagen sind %1$s höher als die vorherigen 7 Tage. - Vorherige 7 Tage - Letzte 7 Tage - %d Wochen 1 Woche + %d Wochen + Letzte 7 Tage + Vorherige 7 Tage + Deine Aufrufe in den letzten 7 Tagen sind %1$s höher als die vorherigen 7 Tage. + Deine Aufrufe in den letzten 7 Tagen sind %1$s niedriger als die vorherigen 7 Tage. + Deine Besucherzahlen in den letzten 7 Tagen sind %1$s höher als in den vorherigen 7 Tagen. + Deine Besucherzahlen in den letzten 7 Tagen sind %1$s niedriger als in den vorherigen 7 Tagen. + %1$s höher als in den vorherigen 7 Tagen + %1$s niedriger als in den vorherigen 7 Tagen + Alle Antworten anzeigen + Jetpack-App sichern Von <b>DayOne</b> Ausblenden Später daran erinnern - Die Statistiken, der Reader, die Benachrichtigungen und weitere Funktionen werden bald in die Jetpack-Mobil-App verschoben. Zur Jetpack-App wechseln Weitere Informationen auf jetpack.com Der Wechsel ist kostenlos und dauert nur eine Minute. Statistiken, der Reader, Benachrichtigungen und weitere, von Jetpack unterstützte Funktionen werden bald aus der WordPress-App entfernt. Statistiken, der Reader, Benachrichtigungen und weitere, von Jetpack unterstützte Funktionen werden am %s aus der WordPress-App entfernt. + Die Statistiken, der Reader, die Benachrichtigungen und weitere Funktionen werden bald in die Jetpack-Mobil-App verschoben. Jetpack-Funktionen werden in Kürze verschoben. Benachrichtigungen werden in die Jetpack-App verschoben Der Reader wird in die Jetpack-App verschoben @@ -154,9 +154,9 @@ Language: de Kategorie wird gelöscht Kategorie wird aktualisiert Kategorie aktualisieren - Beiträge von diesem Benutzer werden nicht länger angezeigt - Benutzer sperren Diesen Benutzer melden + Benutzer sperren + Beiträge von diesem Benutzer werden nicht länger angezeigt Links in WordPress öffnen Offenbar hast du die Jetpack-App installiert.\n\nMöchtest du Links in Zukunft in der Jetpack-App öffnen?\n\nDu kannst dies jederzeit unter „App-Einstellungen“ > „Links in Jetpack öffnen“ ändern Links in Jetpack öffnen? @@ -229,11 +229,10 @@ Language: de Benachrichtigungen werden von Jetpack bereitgestellt Schau dir an, wie der Traffic steigt und erfahre mehr über deine Zielgruppe – mit überarbeiteten Statistiken und Einsichten, jetzt verfügbar in der neuen Jetpack-App. Statistiken werden von Jetpack bereitgestellt - Finde alle deine Lieblingswebsites und Beiträge, folge ihnen und markiere sie mit einem „Like“ – mit Reader, jetzt verfügbar in der neuen Jetpack-App. Reader wird von Jetpack bereitgestellt + Finde alle deine Lieblingswebsites und Beiträge, folge ihnen und markiere sie mit einem „Like“ – mit Reader, jetzt verfügbar in der neuen Jetpack-App. Die neue Jetpack-App hat Statistiken, Reader, Benachrichtigungen und mehr, das dein WordPress verbessert. WordPress ist besser mit Jetpack - Führe ein Tarif-Upgrade durch, um Video-Cover zu verwenden Führe ein Tarif-Upgrade durch, um Audiodateien hochzuladen Von Jetpack unterstützt Ungültige URL. @@ -241,33 +240,34 @@ Language: de Weiter zu Benachrichtigungen Weiter zu Statistiken Weiter zum Reader + Führe ein Tarif-Upgrade durch, um Video-Cover zu verwenden Die neue Jetpack-App ausprobieren Bei der Anzeige des Blocks ist ein Problem aufgetreten. \nTippe, um die Wiederherstellung des Blocks zu versuchen. Letzte Woche hattest du %1$s Aufrufe und %2$s Kommentare Letzte Woche hattest du %1$s Aufrufe und %2$s Likes Letzte Woche hattest du %1$s Aufrufe. - Letzte Woche hattest du %1$s Aufrufe, %2$s Likes und %3$s Kommentare. ⭐️Dein neuster Beitrag %1$s hat %2$s Like erhalten. + Letzte Woche hattest du %1$s Aufrufe, %2$s Likes und %3$s Kommentare. Angetrieben von Jetpack Bild, das anzeigt, dass der Scan des Anmeldecodes läuft Bild, das einen Fehler anzeigt Bist du sicher, dass du fortfahren möchtest? Scan des Anmeldecode beenden Du konntest mit diesem Anmeldecode nicht angemeldet werden. Bitte tippe auf den Button „Erneut scannen“, um den Code erneut zu scannen. + Keine Verbindung + Erneut scannen + Du bist angemeldet! Authentifizierung fehlgeschlagen Dieser Anmeldecode ist abgelaufen. Bitte tippe auf den Button „Erneut scannen“, um den Code erneut zu scannen. Abgelaufener Anmeldecode Der gescannte Anmeldecode konnte nicht validiert werden. Bitte tippe auf den Button „Erneut scannen“, um den Code erneut zu scannen. Anmeldecode konnte nicht validiert werden Für das Scannen von Anmeldecodes ist eine aktive Internetverbindung erforderlich - Keine Verbindung - Erneut scannen - Verwerfen - Tippe auf „Verwerfen“ und navigiere zu deinem Webbrowser zurück, um fortzufahren. - Du bist angemeldet! - Ja, melde mich an Scanne nur QR-Codes, die direkt von deinem Webbrowser kommen. Scanne niemals einen Code, der dir von jemand anderem geschickt wurde. Versuchst du dich in der Nähe von %1$s in deinem Webbrowser anzumelden? + Ja, melde mich an + Tippe auf „Verwerfen“ und navigiere zu deinem Webbrowser zurück, um fortzufahren. + Verwerfen Versuchst du dich in der Nähe von %2$s in %1$s anzumelden? 💡Andere Blogs zu kommentieren ist ein guter Weg, Aufmerksamkeit zu erregen und Follower für deine neue Website zu gewinnen. 💡Tippe auf „MEHR ANZEIGEN“, um dir deine Top-Kommentatoren anzeigen zu lassen. @@ -278,52 +278,52 @@ Language: de 💡Verbessere dein Blog schneller mit dem Kurs <i>Einführung in das Bloggen</i>, der von Experten geleitet wird. Blog-Vorschläge werden geladen. Bitte warte einen Moment und versuche es dann erneut. Du kannst dich nicht entscheiden? Du kannst das Theme jederzeit ändern. + Mehr erfahren + Suche + WordPress + Aufrufe + Planen Bloggen Für dich ausgewählt Das Beste für %s Vorschau für Theme %s anzeigen Wähle ein Theme Heutigen Blog-Vorschlag übersprungen - Mehr erfahren Gesamt Sonstiges - Suche - WordPress - Aufrufe - Planen Deinen Beitrag planen Erinnerungen festlegen Deine Blog-Erinnerungen einrichten Verlauf überprüfen Vergrößere deine Reichweite - Du kannst Blöcke auch neu anordnen, indem du auf einen Block tippst und ihn dann mit den Aufwärts- und Abwärtspfeilen, die unten links auf dem Block erscheinen, nach oben oder unten verschiebst. Bilddatei nicht gefunden. - Mit Drag-and-drop ist das Neuanordnen von Blöcken ganz einfach. Halte einfach einen Block gedrückt, zieh ihn an seine neue Position und lass ihn dann los. - Drag-and-drop - Pfeil-Buttons + Anmeldecode scannen %1$s. Aktuell ausgewählt: %2$s Alle Aufgaben erledigt Aufgabe abgeschlossen - Anmeldecode scannen + Pfeil-Buttons + Mit Drag-and-drop ist das Neuanordnen von Blöcken ganz einfach. Halte einfach einen Block gedrückt, zieh ihn an seine neue Position und lass ihn dann los. + Drag-and-drop + Du kannst Blöcke auch neu anordnen, indem du auf einen Block tippst und ihn dann mit den Aufwärts- und Abwärtspfeilen, die unten links auf dem Block erscheinen, nach oben oder unten verschiebst. ⭐️Dein neuster Beitrag %1$s hat %2$s Likes. Nicht genug Aktivität. Schau später nochmal vorbei, wenn mehr Besucher auf deiner Website waren! - %1$s, %2$s%% aller Follower %1$s (%2$s%%) - Link kopieren - Gratulation! Du kennst dich aus<br/> + %1$s, %2$s%% aller Follower Die App kennenlernen - Bringe Medien direkt von deinem Gerät oder Kamera auf deine Website Lade Fotos oder Videos hoch + Gratulation! Du kennst dich aus<br/> + Link kopieren + Bringe Medien direkt von deinem Gerät oder Kamera auf deine Website + Video-Vorschaubild + Top-Kommentatoren + Deine Benachrichtigungen ansehen Erhalte Echtzeitupdates von überall aus Wähle %1$s Medien %2$s, um deine aktuelle Bibliothek zu sehen. Erhalte Echtzeitupdates von überall aus. - Deine Benachrichtigungen ansehen Wähle das %1$s Benachrichtigungen-Tab %2$s, um jederzeit Aktualisierungen zu erhalten. Wähle %1$s Plus %2$s, um Medien hochzuladen. Du kannst sie von jedem Gerät aus in deine Beiträge/Seiten einfügen. Benutze <b> Entdecken </b>, um Websites und Tags zu finden. Benutze <b> Entdecken </b>, um Websites und Tags zu finden. Versuche, die %1$s Einstellungen %2$s auszuwählen, um Themen deiner Wahl hinzuzufügen. - Video-Vorschaubild - Top-Kommentatoren Vor %1$d Jahren veröffentlicht Vor einem Jahr veröffentlicht Vor %1$d Monaten veröffentlicht @@ -335,25 +335,25 @@ Language: de Vor %1$d Minuten veröffentlicht Vor einer Minute veröffentlicht Vor wenigen Sekunden veröffentlicht - Followers gesamt Kommentare gesamt Likes gesamt - Ausblenden - Antwort - Tägliche Aufforderung + Followers gesamt Verstanden + Antwort Tippe auf <b>%1$s</b>, um deine Website anzuzeigen + Tägliche Aufforderung + Ausblenden Wähle %1$s Reader %2$s aus, um andere Websites zu finden. - Weitere Informationen zu den Aufforderungen - Video nicht ausgewählt - Video ausgewählt - Medien-Vorschaubild 🔥 Beliebteste Zeit + Medien-Vorschaubild + Video ausgewählt + Video nicht ausgewählt + Weitere Informationen zu den Aufforderungen %1$s %2$s - Dashboard besuchen Deine Website ist bereits durch VaultPress geschützt. Klicke auf den nachfolgenden Button, um zu deinem VaultPress-Dashboard zu gelangen. - Deine Website hat VaultPress + Dashboard besuchen Aktuelle Sprache: + Deine Website hat VaultPress Website erstellen Blöcke hinzufügen Erster Bildschirm @@ -386,7 +386,6 @@ Language: de OK http(s):// Link einfügen - Beta Editor wird geladen Inhaltliche Struktur kann nicht abgerufen werden Blöcke: %1$d\nWörter: %2$d\nZeichen: %3$d @@ -395,8 +394,9 @@ Language: de Wähle eine Mediendatei aus der Galerie Foto oder Video mit der Kamera aufnehmen %d px - OK Warte bitte, bis alle Dateien gespeichert wurden + Beta + OK Dateien werden gespeichert Inhalt Dreh einen Film über dein Leben. @@ -405,10 +405,10 @@ Language: de Hinweis: Wir zeigen dir jeden Tag einen neuen Themenvorschlag in deinem Dashboard, um deine Kreativität anzuregen! Wenn du deine Schreibkünste verbessern willst, kreiere deinen eigenen Schreibstil und teile ihn mit anderen – und dabei helfen dir unsere Themenvorschläge! - Einführung\nBlog-Schreibanregungen Erinnerungen festlegen - Eine Blog-Schreibanregung einschließen Durch regelmäßiges Veröffentlichen von Beiträgen gewinnst du neue Leser. Sag uns, wann du etwas schreiben möchtest. Dann senden wir dir eine Erinnerung! + Einführung\nBlog-Schreibanregungen + Eine Blog-Schreibanregung einschließen Verbessere deine Schreibkünste, indem du deinen eigenen Schreibstil entwickelst Kreatives Schreiben und Poesie Reisen @@ -423,10 +423,8 @@ Language: de Nachrichten Musik Lokale Dienstleistungen - Lifestyle Innenarchitektur Gesundheit - Gaming Essen Fitness und Sport Film und Fernsehen @@ -435,16 +433,18 @@ Language: de Heimwerken Bildung Community und gemeinnützige Organisationen + Lifestyle + Gaming Geschäft Bücher - Beauty Automobil Kunst - z. B. Mode, Poesie, Politik Website-Thema Tippe zum Fortfahren auf <b>%1$s</b>. - Für heute überspringen Mehr Themenvorschläge anzeigen + z. B. Mode, Poesie, Politik + Beauty + Für heute überspringen %d Antworten Blog-Vorschlag teilen ✓ Geantwortet @@ -454,11 +454,11 @@ Language: de Diese Farbkombination ist unter Umständen für manche Menschen schwer lesbar. Wähle eine hellere Hintergrundfarbe und/oder eine dunklere Textfarbe. Diese Farbkombination ist unter Umständen für manche Menschen schwer lesbar. Wähle eine dunklere Hintergrundfarbe und/oder eine hellere Textfarbe. Das Einfügen des Mediums ist fehlgeschlagen.\nTippe für weitere Informationen. - Wähle ein Thema aus der unten stehenden Liste aus oder gib ein eigenes ein. Worum wird es auf deiner Website gehen? - Wöchentliche Zusammenfassung - Startseite + Wähle ein Thema aus der unten stehenden Liste aus oder gib ein eigenes ein. Kategorie wird hinzugefügt + Startseite + Wöchentliche Zusammenfassung Welche E-Mail-Anwendung verwendest du? Bei der Kommunikation mit der Website ist ein Problem aufgetreten. Es wurde ein HTTP-Fehlercode 401 zurückgegeben. XML-RPC-Anrufe sind auf dieser Website anscheinend blockiert (Fehlercode 401). Wenn der Anmeldeversuch fehlschlägt, tippe auf das Hilfe-Icon, um die FAQ anzuzeigen. @@ -467,71 +467,71 @@ Language: de Menü Deine Suche beinhaltet Zeichen, die in Domains von WordPress.com nicht unterstützt werden. Die folgenden Zeichen sind erlaubt: A–Z, a–z, 0–9. Überprüfe deine Internetverbindung und lade die Seite neu. - Zu den Statistiken Heutige Statistiken Während des Aktualisierens des Benachrichtigungsinhalts ist ein Fehler aufgetreten + Zu den Statistiken Bearbeiten - Das Moderieren der Kommentare ist fehlgeschlagen In den Papierkorb verschieben Als Spam markieren + Das Moderieren der Kommentare ist fehlgeschlagen Zurückweisen Einstellungen für gekachelte Galerien Navigiert zum Layout-Auswahlbildschirm Galerie-Stil - Internet öffnen Du kannst dein Facebook-Konto auf der WordPress.com-Website verbinden. Wenn du fertig bist, kehre zur WordPress-App zurück, um deine Teilen-Einstellungen zu ändern. - App-Icon - Zurück-Icon - Automattic-Logo + Internet öffnen WordPress - WooCommerce - Tumblr - Simplenote - Pocket Casts + Automattic-Logo + Zurück-Icon + App-Icon Jetpack Tag eins Quelltext Datenschutzerklärung + Pocket Casts + Simplenote + Tumblr + WooCommerce Nutzungsbedingungen Arbeite von überall aus - Arbeite bei uns - Automattic-Familie - Rechtliches und mehr - Twitter Instagram + Twitter + Rechtliches und mehr + Automattic-Familie Bewerte uns - Mit Freunden teilen Du kannst diesen Block über die Webversion des Editors bearbeiten. - Jetpack-Security-Einstellungen öffnen + Mit Freunden teilen + Arbeite bei uns Hinweis: Du musst die WordPress.com-Anmeldung zulassen, um diesen Block im mobilen Editor zu bearbeiten. - Hinweis: Das Layout kann je nach Theme und Bildschirmgröße variieren - Adress-Einstellungen + Jetpack-Security-Einstellungen öffnen MEDIEN HINZUFÜGEN + Adress-Einstellungen + Hinweis: Das Layout kann je nach Theme und Bildschirmgröße variieren Wir haben momentan Probleme, die Daten deiner Website zu laden. Einige Daten wurden nicht geladen - Das Dashboard ist nicht aktualisiert. Überprüfe deine Verbindung und ziehe zum Aktualisieren den Bildschirm nach unten. - Das Dashboard konnte nicht aktualisiert werden. Das Video wurde nicht hochgeladen! Für das Hochladen von Videos, die länger als 5 Minuten dauern, ist ein kostenpflichtiger Tarif erforderlich. + Das Dashboard konnte nicht aktualisiert werden. + Das Dashboard ist nicht aktualisiert. Überprüfe deine Verbindung und ziehe zum Aktualisieren den Bildschirm nach unten. Danksagungen Datenschutzhinweis für Kalifornien - Version %1$s - Dank an Rechtliches und mehr Über %1$s - Blog Die Grundlagen Ausgewählt: Standard Weitere Support-Optionen Unterstützung erhalten Schriftgröße Zum Auswählen der Schriftgröße zweimal tippen + Version %1$s + Dank an + Blog Zum Auswählen der Standardschriftgröße zweimal tippen Support kontaktieren - %1$s (%2$s) Unterhaltung folgen Als Erster kommentieren Alle Kommentare anzeigen Beim Abrufen der Beitragsdaten ist ein Fehler aufgetreten + %1$s (%2$s) Beim Abrufen der Kommentare ist ein Fehler aufgetreten Einstellungen für „Unterhaltung folgen“ Aus der Zwischenablage @@ -549,10 +549,10 @@ Language: de Autor Link kopieren Mit einer individuellen Domain ist deine Website für Besucher leichter zu finden + Ohne Titel + Erstelle deinen ersten Beitrag Deine Domain hinzufügen Beiträge werden auf deiner Blogseite in umgekehrter chronologischer Reihenfolge angezeigt. Es ist an der Zeit, deine Ideen mit der Welt zu teilen! - Erstelle deinen ersten Beitrag - Ohne Titel Anstehende geplante Beiträge An einem Beitragsentwurf arbeiten <span style=\"color:#008000;\">Kostenlos für das erste Jahr </span><span style=\"color:#50575e;\"><s>%s/Jahr</s></span> @@ -560,24 +560,24 @@ Language: de Link erstellen Deine neue Domain <b>%s</b> wird gerade eingerichtet. Es kann bis zu 30 Minuten dauern, bis deine Domain funktioniert. Glückwunsch zu deinem Kauf! - Domain auswählen Domains Oben gehalten Beitrag auf der Startseite halten Als oben gehalten markieren - Unterhaltung nicht mehr folgen - In-App-Benachrichtigungen aktivieren Du folgst dieser Unterhaltung. Du wirst per E-Mail benachrichtigt, wenn neue Kommentare veröffentlicht werden. - Optionen zum Verfolgen von Unterhaltungen verwalten, Pop-up-Fenster + In-App-Benachrichtigungen aktivieren + Unterhaltung nicht mehr folgen + Domain auswählen In-App-Benachrichtigungen konnten nicht deaktiviert werden In-App-Benachrichtigungen konnten nicht aktiviert werden - In-App-Benachrichtigungen deaktiviert - In-App-Benachrichtigungen aktiviert - Von dieser Unterhaltung abgemeldet + Optionen zum Verfolgen von Unterhaltungen verwalten, Pop-up-Fenster Dieser Unterhaltung wird gefolgt\nIn-App-Benachrichtigungen aktivieren? + Von dieser Unterhaltung abgemeldet + In-App-Benachrichtigungen aktiviert + In-App-Benachrichtigungen deaktiviert Domain suchen - Auf dieser Website erworbene Domains werden Besucher zu <b>%s</b> weiterleiten In deinem Tarif ist eine kostenlose Domain-Registrierung für ein Jahr enthalten + Auf dieser Website erworbene Domains werden Besucher zu <b>%s</b> weiterleiten Kostenlose Domain in Anspruch nehmen Domains verwalten Domain hinzufügen @@ -590,7 +590,6 @@ Language: de <span style=\"color:#B26200;\">%1$s für das erste Jahr </span><span style=\"color:#50575e;\"><s>%2$s/Jahr</s></span> %s<span style=\"color:#50575e;\"> /Jahr</span> Möchtest du sie verwerfen? - Es sind nicht gespeicherte Änderungen vorhanden Kommentar darf nicht leer sein Benutzer-E-Mail-Adresse ist ungültig Web-Adresse ist ungültig @@ -600,26 +599,27 @@ Language: de Kommentar Name Fertig + Es sind nicht gespeicherte Änderungen vorhanden Vorschauen für Einbettungen-Blöcke sind demnächst verfügbar Wöchentliche Zusammenfassung Einbettungsoptionen Zum Anzeigen der Einbettungsoptionen zweimal tippen. Website erstellt! Schließe eine weitere Aufgabe ab. + <a href=\"\">Dir und %1$s Blogger</a> gefällt das. <a href=\"\">%1$s Blogger</a> gefällt das. <a href=\"\">1 Blogger</a> gefällt das. - <a href=\"\">Dir und %1$s Blogger</a> gefällt das. <a href=\"\">Dir und 1 Blogger</a> gefällt das. <a href=\"\">Dir</a> gefällt das. - Zeilenhöhe - Hol dir deine Domain - %s Unbekannter Fehler beim Abrufen des empfohlenen App-Templates - Ungültige Antwort erhalten - Keine Antwort erhalten - Automattic-Apps – Apps für jeden Bildschirm + %s + Hol dir deine Domain + Zeilenhöhe + Domains Teile WordPress mit einem Freund + Keine Antwort erhalten + Ungültige Antwort erhalten Direkte Links - Domains + Automattic-Apps – Apps für jeden Bildschirm Wöchentliche Zusammenfassung: %s Zeit für Benachrichtigungen Du erhältst <b>jeden Tag</b> um <b>%s</b> Uhr eine Erinnerung zum Bloggen. @@ -649,34 +649,34 @@ Language: de Blocks sind Teile deines Inhalts, die du ganz ohne Coding-Kenntnisse einfügen, neu anordnen und gestalten kannst. Blocks sind eine einfache und moderne Art und Weise, wunderschöne Layouts zu erstellen. Blocks geben dir die Möglichkeit, dich voll und ganz auf das Verfassen deiner Inhalte zu konzentrieren. Alle Tools zur Formatierung sind vorhanden, damit du deine Ideen und Meinungen ganz nach deinen Wünschen präsentieren kannst. Ordne deinen Inhalt in Spalten an und füge Buttons mit Handlungsaufrufen sowie überlagerte Texte auf Bildern hinzu. - Du kannst jederzeit einen neuen Block hinzufügen, indem du auf das Icon „+“ in der Werkzeugleiste unten links klickst. %1$s von %2$s abgeschlossen + Du kannst jederzeit einen neuen Block hinzufügen, indem du auf das Icon „+“ in der Werkzeugleiste unten links klickst. Lerne die Grundlagen mit einer kurzen Erklärung. Das Moderieren von einem oder mehrerer Kommentare ist fehlgeschlagen Website erstellen - Richte deine Website mit wenigen schnellen Schritten ein Erstelle deine WordPress-Website - Website-Statistiken können nicht aktiviert werden Website-Statistiken aktivieren + Richte deine Website mit wenigen schnellen Schritten ein + Website-Statistiken können nicht aktiviert werden Aktiviere die Website-Statistiken, um ausführliche Informationen zu deinem Traffic, deinen Likes, Kommentaren und Abonnenten anzuzeigen. - Du suchst die Statistiken? Was ist ein Block? + Du suchst die Statistiken? Wir arbeiten daran, Unterstützung für %s-Vorschauen hinzuzufügen. In der Zwischenzeit kannst du den eingebetteten Inhalt auf deinem Beitrag als Vorschau sehen. Wir arbeiten daran, Unterstützung für %s-Vorschauen hinzuzufügen. In der Zwischenzeit kannst du den eingebetteten Inhalt auf deiner Seite als Vorschau sehen. + Keine Blöcke gefunden Medien können nicht eingebettet werden Versuche es mit einem anderen Suchbegriff - Keine Blöcke gefunden %s-Vorschauen noch nicht verfügbar Embed-Block-Vorschau für %s-Inhalte demnächst verfügbar Zur Vorschau des Beitrags zweimal tippen Zur Vorschau der Seite zweimal tippen Auf dem Browser-Tab deines Besuchers und an anderen Stellen online anzeigen Zeig mir alles + Es tut uns leid, aber Jetpack Scan ist derzeit nicht mit WordPress-Multisite-Installationen kompatibel. + Wähle eine Website aus, die geöffnet werden soll + Du kannst die Websites jederzeit wechseln. Brauchst du ein wenig Hilfe dabei, diese Website mit der App zu verwalten? Eine neue Website erstellen - Du kannst die Websites jederzeit wechseln. - Wähle eine Website aus, die geöffnet werden soll - Es tut uns leid, aber Jetpack Scan ist derzeit nicht mit WordPress-Multisite-Installationen kompatibel. WordPress-Multisites werden nicht unterstützt Ungültige URL. Bitte gib eine gültige URL ein. Beschriftung einbetten %s @@ -689,9 +689,9 @@ Language: de Lege fest, an welchen Tagen du bloggen willst Unter „Meine Website“ &rarr; „Einstellungen“ &rarr; „Blog-Erinnerungen“ kannst du dies jederzeit aktualisieren. Du hast keine Erinnerungen festgelegt. - Du erhältst %1$swöchentlich am %2$s um %3$s Uhr eine Erinnerung zum Bloggen. Erinnerungen entfernt! Fertig! + Du erhältst %1$swöchentlich am %2$s um %3$s Uhr eine Erinnerung zum Bloggen. Aktualisieren Nicht festgelegt %s pro Woche @@ -699,9 +699,9 @@ Language: de Richte Blog-Erinnerungen für die Tage ein, an denen du einen Beitrag erstellen möchtest. Dein Beitrag wird veröffentlicht. In der Zwischenzeit kannst du Blog-Erinnerungen für Tage einrichten, an denen du einen Beitrag erstellen möchtest. Festlegen deiner Blog-Erinnerungen - Dies ist deine Erinnerung, heute kreativ zu sein Am %s ist es Zeit, einen Beitrag zu veröffentlichen Das Bearbeiten von wiederverwendbaren Blöcken wird in WordPress für iOS noch nicht unterstützt + Dies ist deine Erinnerung, heute kreativ zu sein Das Bearbeiten von wiederverwendbaren Blöcken wird in WordPress für Android noch nicht unterstützt Alternativ kannst du diese Blöcke loslösen und separat bearbeiten, indem du auf „In normale Blöcke umwandeln“ tippst. Fertig @@ -713,8 +713,8 @@ Language: de WordPress für Android-Support Kategorien deiner Website verwalten Kategorien - Erinnerungen Der Inhalt der Seite mit deinen letzten Beiträgen wird automatisch generiert und kann nicht bearbeitet werden. + Erinnerungen Rahmeneinstellungen Nicht erneut anzeigen Speicher anzeigen @@ -737,8 +737,8 @@ Language: de Doppelt tippen, um Action Sheet zu öffnen und Bild oder Video hinzuzufügen Aktuelle Einheit ist %s Mehrfach posten - %s in normalen Block umgewandelt Spalten-Einstellungen + %s in normalen Block umgewandelt Link hinzufügen zu %s Linktext hinzufügen Bild oder Video hinzufügen @@ -755,13 +755,13 @@ Language: de Wenn du bereits eine Website hast, musst du das kostenlose Jetpack-Plugin installieren und es mit deinem WordPress.com-Konto verbinden. Dein Profilfoto Um diese App für %1$s zu verwenden, muss das Jetpack-Plugin installiert und mit einem WordPress.com-Konto verbunden sein. - Bild nach vorne verschieben Bild nach hinten verschieben + Bild nach vorne verschieben Breite-Einstellungen - Link-Beziehung Spalteneinstellungen - (Ohne Titel) + Link-Beziehung Website + (Ohne Titel) Benutzerprofil Bottom Sheet-Informationen Liste der Likes %s Zwei @@ -769,18 +769,18 @@ Language: de Social-Media-Symbol für %s Erwähnung NEU - Beitragsvorschau Seitenvorschau + Beitragsvorschau Erneut versuchen GIF Eins Keine Vorschau verfügbar Textfarbe Innenabstand - Vier Beitragsbild - Individuelle URL + Vier Einbettung erstellen + Individuelle URL Spalte %d Gib eine kurze Beschreibung des Links für Benutzer von Screenreadern an Blöcke hinzufügen @@ -789,11 +789,11 @@ Language: de %s umwandeln in Block umwandeln … Das Einfügen des Mediums ist fehlgeschlagen. - Das Einfügen der Audiodatei ist fehlgeschlagen. - Beschreibe den Zweck des Bildes. Lass dieses Feld frei, falls das Bild rein dekorativ ist. %1$s umgewandelt in %2$s Fehler beim Laden der „Like“-Daten. %s. %d Gefällt mir + Beschreibe den Zweck des Bildes. Lass dieses Feld frei, falls das Bild rein dekorativ ist. + Das Einfügen der Audiodatei ist fehlgeschlagen. 1 Like Vorschlag: Icon-Button verwenden @@ -801,13 +801,13 @@ Language: de Button suchen Aktueller Button-Text ist Blöcke suchen Blocklabel suchen Aktueller Text ist - Außen Kein individueller Platzhalter eingestellt Innen Suchüberschriften ausblenden Zum Bearbeiten des Platzhaltertexts zweimal tippen Zum Bearbeiten des Label-Texts zweimal tippen Zum Bearbeiten des Button-Texts zweimal tippen + Außen Zum Wechseln der Einheit zweimal tippen Aktueller Platzhaltertext ist Suche löschen @@ -819,23 +819,23 @@ Language: de Kein Netzwerk verfügbar Keine unbeantworteten Kommentare Unbeantwortet - LINK HINZUFÜGEN Sucheinstellungen + LINK HINZUFÜGEN IP-Adressen auf der Liste „Immer zulassen“ Gesperrte Kommentare Button-Text hinzufügen. Themen folgen + Herunterladen Eine neue Möglichkeit, ansprechende Inhalte auf deiner Website zu erstellen und zu veröffentlichen. Ausblenden - Herunterladen Bedrohungen wurden erfolgreich behoben. Bitte bestätige, dass du alle %s aktiven Bedrohungen beheben möchtest. Beim Scan wurden %1$s mögliche Bedrohungen bei %2$s gefunden. Prüfe diese bitte unten und führe die erforderliche Aktion aus oder tippe auf den Button „Alle beheben“. Wir sind %3$s, wenn du uns brauchst. Wir arbeiten im Hintergrund daran, diese Bedrohungen zu beheben. In der Zwischenzeit kannst du deine Website ganz normal verwenden und jederzeit nachsehen, wie weit der Scan schon ist. Fokuspunkt bearbeiten + beispiel.com Tippe zweimal, um das Bottom Sheet zu öffnen und das Bild zu bearbeiten, auszutauschen oder zu löschen Tippe zweimal, um das Action Sheet zu öffnen und das Bild zu bearbeiten, auszutauschen oder zu löschen - beispiel.com Gib einen Namen für deine Website ein <b>Alle Aufgaben abgeschlossen</b><br/>Du wirst nun mehr Personen erreichen. Gute Arbeit! <b>Alle Aufgaben abgeschlossen</b><br/>Du hast deine Website angepasst. Gut gemacht! @@ -849,26 +849,26 @@ Language: de Beim Abrufen von Rollen ist ein Fehler aufgetreten Unbekannter Fehler beim Abrufen von Daten zu Einladungs-Links Verwende diesen Link, um deine Teammitglieder einzuladen. Jeder, der diese URL besucht, kann sich bei deiner Organisation registrieren, auch wenn er oder sie den Link von jemand anderem erhalten hat. Teile ihn also nur mit vertrauenswürdigen Personen. + Einladungslink Läuft ab %1$s Einladungslink deaktivieren Einladungs-Link teilen Neuen Link generieren Link-Status aktualisieren - Einladungslink - Bedrohung gefunden Bedrohungen gefunden + Bedrohung gefunden <b>Scan abgeschlossen</b> <br> %s potenzielle Bedrohungen gefunden <b>Scan abgeschlossen</b> <br> Eine potenzielle Bedrohung gefunden <b>Scan abgeschlossen</b> <br> Keine Bedrohungen gefunden - Bedrohung wird behoben Deaktivieren - Dies lösen + Bedrohung wird behoben Prüfe deine Seiten und nimm Änderungen vor. Du kannst auch Seiten hinzufügen oder entfernen. - Sieh dir deine Website an + Dies lösen Entdecke und folge Websites, die dich inspirieren. - Teilen über soziale Netzwerke Neue Beiträge automatisch in deinen sozialen Medien teilen. Wähle einen Namen für deine Website, der am besten zu ihrer Persönlichkeit und Ausrichtung passt. + Teilen über soziale Netzwerke + Sieh dir deine Website an Überprüfe deine Website-Statistiken Wir versuchen weiterhin, deine Backup-Datei zum Herunterladen zu erstellen. Wir konnten den Status nicht finden, der angibt, wie lange dein Backup zum Herunterladen dauert. @@ -897,7 +897,6 @@ Language: de Schloss-Icon Audiodatei kann nicht eingefügt werden. Für Optionen hier tippen. Zum Auswählen einer Audiodatei zweimal tippen - Zum Anzuhören der Audiodatei zweimal tippen Audio-Datei wählen Audio-Player Audiodatei @@ -908,18 +907,19 @@ Language: de Diese Audiodatei verwenden Audio auf Gerät auswählen Optional: Gib eine individuelle Nachricht ein, die zusammen mit deiner Einladung gesendet wird. - Weitere Informationen zu den Rollen + Zum Anzuhören der Audiodatei zweimal tippen Fixiert Gefunden hier, um zu helfen Beim Scan wurde eine mögliche Bedrohung bei %1$s gefunden. Prüfe die Bedrohung bitte unten und führe die erforderliche Aktion aus oder tippe auf den Button „Alle beheben“. Wir sind %2$s, wenn du uns brauchst. + Weitere Informationen zu den Rollen Um deine Website noch einmal zu prüfen, führe einen manuellen Scan aus oder warte, bis deine Website heute zu einem späteren Zeitpunkt von Jetpack gescannt wird. Willkommen bei Jetpack Scan! Wir bereiten gerade einen vollständigen Scan vor und sehen uns deine Website genau an. Wir geben dir Bescheid, wenn wir etwas sehen, das den Scan beeinträchtigen könnte. Anschließend beginnt dein erster vollständiger Scan. Willkommen bei Jetpack Scan! Wir sehen uns deine Website jetzt an und teilen dir die Ergebnisse bald mit. Wir arbeiten im Hintergrund daran, die Bedrohung zu beheben. In der Zwischenzeit kannst du deine Website ganz normal verwenden und jederzeit nachsehen, wie weit der Scan schon ist. Du erhältst eine Benachrichtigung, wenn eine Bedrohung gefunden wird. In der Zwischenzeit kannst du deine Website ganz normal verwenden und jederzeit nachsehen, wie weit der Scan schon ist. - Bedrohungen werden behoben Jetpack Scan konnte einen Scan deiner Website ausführen. Schau bitte nach, ob deine Website erreichbar ist. Wenn ja, versuche es erneut. Wenn sie nicht erreichbar ist oder wenn mit Jetpack Scan weiterhin Probleme auftreten, wende dich bitte an unser Support-Team. + Bedrohungen werden behoben Etwas ist schiefgelaufen Erstellung eines Backups der Website Erstellung eines Backups der Website von %1$s %2$s @@ -928,14 +928,14 @@ Language: de Deine Website wurde erfolgreich gesichert\nBackup erstellt von %1$s %2$s Deine Website wird gesichert\nBackup wird erstellt von %1$s %2$s Audio-Datei auswählen - Es wird gerade eine andere Wiederherstellung durchgeführt. Fehler-Icon Fertig-Button + Es wird gerade eine andere Wiederherstellung durchgeführt. + Website besuchen Wiederherstellungsfehler Website besuchen-Button Fertig-Button Wiederherstellen-Button - Website besuchen Alle deine ausgewählten Elemente werden jetzt auf den Stand von %1$s %2$s wiederhergestellt. Deine Website wurde wiederhergestellt. Du brauchst nicht zu warten. Wir benachrichtigen dich, wenn deine Website wiederhergestellt wurde. @@ -943,47 +943,46 @@ Language: de Wir stellen deine Website auf %1$s %2$s wieder her. Website wird derzeit wiederhergestellt Button für Websitewiederherstellung bestätigen - Bild mit rotem Kreis und Ausrufezeichen Warnung + Bild mit rotem Kreis und Ausrufezeichen Button für Websitewiederherstellung - Wiederherstellen-Button Website wiederherstellen + Wiederherstellen + Fertig + Wiederherstellen-Button %1$s %2$s ist der ausgewählten Punkt für deine Wiederherstellung. Website wiederherstellen Auswahl der Elemente zur Wiederherstellung: - Wiederherstellen Button für Wolke mit X Fertig-Button - Fertig - Download fehlgeschlagen Tablet Mobil + Download fehlgeschlagen Nicht erneut anzeigen Anheften Wähle %1$s Seiten %2$s aus, um deine Seitenliste anzuzeigen. Du kannst die Seiten deiner Website ändern, hinzufügen oder entfernen. Website-Seiten prüfen Wähle %1$s Startseite %2$s aus, um deine Homepage zu bearbeiten. - Als nicht gesehen markieren Als gesehen markieren + Als nicht gesehen markieren Medien-Upload fehlgeschlagen.\n%1$s Nicht genügend verfügbarer Websitespeicher Gesehen-Status dieses Beitrags kann nicht umgeschaltet werden Als nicht gesehen markiert Beitrag als gesehen markiert Fehler beim Abrufen des Behebungsstatus. Bitte kontaktiere den Support. - Die Bedrohung wurde erfolgreich behoben. Fehler beim Beheben von Bedrohungen. Bitte kontaktiere den Support. + Die Bedrohung wurde erfolgreich behoben. Bitte bestätige, dass du eine aktive Bedrohung beheben möchtest. Alle Bedrohungen beheben Fehler beim Ignorieren der Bedrohung. Bitte kontaktiere den Support. Bedrohung ignoriert. Ein Sicherheitsproblem solltest du nur ignorieren, wenn du dir absolut sicher bist, dass es harmlos ist. Wenn du diese Bedrohung ignorieren möchtest, wird sie auf deiner Website <b>%s</b> verbleiben. Fehler beim Beheben der Bedrohung. Bitte kontaktiere den Support. + Ignoriert Bedrohung ignoriert - Bedrohung behoben am %s Bedrohung wird behoben - Ignoriert Keine Elemente gefunden Fixiert Alle @@ -994,46 +993,47 @@ Language: de Versuche, den Datumsbereich anzupassen Keine passenden Backups gefunden Dein erstes Backup wird innerhalb von 24 Stunden hier bereitgestellt. Du erhältst eine Benachrichtigung, wenn das Backup abgeschlossen ist. + Bedrohung behoben am %s Dein erstes Backup ist bald fertig Bei der Bearbeitung der Anfrage ist ein Problem aufgetreten. Bitte versuche es später erneut. Nach unten verschieben Block-Position ändern - Upload Icon Wir haben dir auch einen Link zu deiner Datei per E-Mail geschickt. + Upload „Link teilen“-Button Download-Button - Herunterladbares Backup fertig-Icon - Link teilen Herunterladen - Wir haben erfolgreich ein Backup deiner Website vom %1$s %2$s erstellt. Du kannst dein Backup nun herunterladen + Link teilen + Herunterladbares Backup fertig-Icon + Wir haben erfolgreich ein Backup deiner Website vom %1$s %2$s erstellt. Dein Backup - Du brauchst nicht zu warten. Wir teilen dir mit, wenn dein Backup fertig ist. Herunterladbares Backup-Icon erstellen Wir erstellen ein herunterladbares Backup deiner Website vom %1$s %2$s. Wir erstellen momentan ein herunterladbares Backup deiner Website + Du brauchst nicht zu warten. Wir teilen dir mit, wenn dein Backup fertig ist. Backup herunterladen - Ein anderer Download läuft gerade. Bei der Bearbeitung der Anfrage ist ein Problem aufgetreten. Bitte versuche es später erneut. + Ein anderer Download läuft gerade. Herunterladbares Backup-Button erstellen %1$s %2$s ist der ausgewählte Punkt, um ein herunterladbares Backup zu erstellen. %1$s · %2$s · %1$s · %2$s %1$s · - auch veröffentlichen Benutzer - Keine passenden %s. - Beim Laden von Vorschlägen ist ein Fehler aufgetreten. - Keine %s Vorschläge verfügbar. - Nimm eine Eingabe vor, um die Liste der Vorschläge zu filtern. - Kostenloses Angebot einholen Bedrohung ignorieren Bedrohung beheben + Kostenloses Angebot einholen + auch veröffentlichen Jetpack Scan beseitigt die Bedrohung. Jetpack Scan bearbeitet die betroffene Datei bzw. das betroffene Verzeichnis. Jetpack Scan wird auf eine neuere Version (%s) aktualisiert. Jetpack Scan löscht die betroffene Datei bzw. das betroffene Verzeichnis. + Keine passenden %s. + Beim Laden von Vorschlägen ist ein Fehler aufgetreten. + Keine %s Vorschläge verfügbar. + Nimm eine Eingabe vor, um die Liste der Vorschläge zu filtern. Jetpack Scan ersetzt die betroffene Datei bzw. das betroffene Verzeichnis. Jetpack Scan kann diese Bedrohung nicht automatisch beheben.\n Wir empfehlen dir, die Bedrohung manuell zu entfernen: Stelle sicher, dass WordPress, dein Theme und alle deine Plugins auf dem neuesten Stand sind und entferne anschließend den betroffenen Code, das betroffene Theme oder das betroffene Plugin von deiner Website. \n \n\n Wenn du weitere Hilfe benötigst, um diese Bedrohung zu beheben, empfehlen wir dir <b>Codeable</b>, einen Marktplatz für vertrauenswürdige Freiberufler mit sorgfältig geprüften WordPress-Experten.\n Von Codeable wurde eine Gruppe ausgewählter Sicherheitsexperten zusammengestellt, um bei diesen Projekten Unterstützung zu leisten. Die Preise reichen von 70 bis 120 USD/Stunde und du kannst kostenlos ein unverbindliches Angebot einholen. Beseitigen der Bedrohung @@ -1048,57 +1048,57 @@ Language: de Bedrohung gefunden %s Schwachstelle in WordPress gefunden Verschiedene Schwachstellen - Gefährdetes Theme: %1$s (Version %2$s) - Gefährdetes Plugin: %1$s (Version %2$s) %s: bösartiges Codemuster Datenbankbedrohung %s - %s: infizierte Core-Datei + Gefährdetes Theme: %1$s (Version %2$s) + Gefährdetes Plugin: %1$s (Version %2$s) + diese Website Bedrohung gefunden - Alle beheben + %s: infizierte Core-Datei vor einigen Sekunden - vor %s Minute(n) vor %s Stunde(n) - diese Website + vor %s Minute(n) + Alle beheben Der letzte Jetpack Scan wurde ausgeführt am %1$s. Dabei wurden keine Risiken festgestellt. %2$s - Deine Website ist möglicherweise gefährdet - Mach dir keine Sorgen - Erneut scannen + Backup Jetzt scannen + Erneut scannen + Mach dir keine Sorgen + Deine Website ist möglicherweise gefährdet Icon für Scan-Status - Backup Aktivitätstyp-Filter (%s Typen ausgewählt) - %1$s (%2$s Elemente werden angezeigt) Aktivitätstyp-Filter Keine Aktivitäten im ausgewählten Zeitraum aufgezeichnet. Keine Aktivitäten verfügbar Bitte überprüfe deine Internetverbindung und versuche es erneut. + %1$s (%2$s Elemente werden angezeigt) Keine Verbindung Aktivitätstyp (%s) Datumsbereich-Filter - Versuche, deinen Zeitraum oder Aktivitätsfilter zu ändern Keine passenden Ereignisse gefunden - Website-Datenbank - (beinhaltet wp-config.php und alle Nicht-WordPress-Dateien) + Versuche, deinen Zeitraum oder Aktivitätsfilter zu ändern Medien-Uploads - WordPress-Plugins WordPress-Themes + WordPress-Plugins Herunterladbares Backup-Icon erstellen - Herunterladbare Datei erstellen - Herunterladbares Backup erstellen - Backup herunterladen - Backup-Download - Fehler - Datei auswählen + Website-Datenbank + (beinhaltet wp-config.php und alle Nicht-WordPress-Dateien) + Aktivitätstyp Backup herunterladen + Datei auswählen Zu diesem Punkt wiederherstellen - Aktivitätstyp + Fehler + Backup herunterladen + Herunterladbares Backup erstellen + Backup-Download + Herunterladbare Datei erstellen Zeitraum + Duplizieren Nach Aktivitätstyp filtern Die Version von dieser App kopieren Den Beitrag zuerst bearbeiten - Der Beitrag, den du zu kopieren versuchst, hat zwei Versionen, die miteinander in Konflikt stehen, oder du hast kürzlich Änderungen vorgenommen, diese aber nicht gespeichert.\nBearbeite zuerst den Beitrag, um den Konflikt zu lösen, oder fahre mit dem Kopieren der Version aus dieser App fort. Synchronisierungskonflikt des Beitrags - Duplizieren + Der Beitrag, den du zu kopieren versuchst, hat zwei Versionen, die miteinander in Konflikt stehen, oder du hast kürzlich Änderungen vorgenommen, diese aber nicht gespeichert.\nBearbeite zuerst den Beitrag, um den Konflikt zu lösen, oder fahre mit dem Kopieren der Version aus dieser App fort. Die Story wird gespeichert, bitte warten… Dateiname Blockeinstellungen der Datei @@ -1110,11 +1110,11 @@ Language: de Domain auswählen Jetpack-Einstellungen Jetpack - Du folgst der Unterhaltung per E-Mail - Unterhaltung per E-Mail folgen Abmeldung von den Kommentaren für diesen Beitrag fehlgeschlagen Abonnement für Kommentare in diesem Beitrag fehlgeschlagen Fehler beim Abrufen des Abonnementstatus für den Beitrag + Du folgst der Unterhaltung per E-Mail + Unterhaltung per E-Mail folgen Ungültige Antwort erhalten Keine Antwort erhalten Löschen @@ -1128,25 +1128,25 @@ Language: de Diese Story wurde auf einem anderen Gerät bearbeitet und die Möglichkeiten, bestimmte Objekte zu bearbeiten, sind ggfs. eingeschränkt. Eingeschränkte Story-Bearbeitung Die Medien wurden entfernt. Versuche, deine Story neu zu erstellen. - Hintergrund - Text + Löschen + Weiter + Fertig + Änderungen verwerfen? Verwerfen + Text + Hintergrund + Layouts sind offline nicht verfügbar Änderungen werden nicht gespeichert. - Änderungen verwerfen? - Fertig - Weiter - Löschen - Beim Auswählen des Themes ist ein Fehler aufgetreten. Bitte überprüfe deine Internetverbindung und versuche es erneut. Tippe auf „Erneut versuchen“, wenn du wieder online bist. - Layouts sind offline nicht verfügbar + Beim Auswählen des Themes ist ein Fehler aufgetreten. + Willkommen! + Scannen + Keine aktuellen Beiträge Mit Store-Anmeldedaten fortfahren Verbundene E-Mail-Adresse suchen Themen folgen Folge mehreren Themen, um deine Suche zu erweitern - Keine aktuellen Beiträge - Willkommen! - Scannen <b>Johan Brandt</b> hat auf deinen Beitrag geantwortet Heute hast du auf deiner Website <b>50 \"Gefällt mir\"-Angaben</b> erhalten: <b>Madison Ruiz</b> gefällt dein Beitrag @@ -1176,18 +1176,18 @@ Language: de Pamela Nguyen Ich finde die Arbeit von Fotograf Cameron Karsten sehr inspirierend. Das nächste Mal probiere ich diese Techniken auch aus Inspiration - Folge deinen Lieblingswebsites und entdecke neue Blogs. Sieh mithilfe von umfassenden Analysen dabei zu, wie deine Zielgruppe wächst. - Kommentare und Benachrichtigungen in Echtzeit anzeigen. Mit dem leistungsstarken Editor kannst du auch von unterwegs aus Beiträge veröffentlichen. Willkommen beim beliebtesten Website-Baukasten der Welt. + Kommentare und Benachrichtigungen in Echtzeit anzeigen. + Folge deinen Lieblingswebsites und entdecke neue Blogs. Laden der Medien fehlgeschlagen Websites, denen du folgen möchtest Wir arbeiten hart daran, mit jeder Veröffentlichung weitere Blöcke hinzuzufügen. ‚%s‘ wird nicht vollständig unterstützt Hilfe-Button - Mit dem Webeditor bearbeiten Bilder auswählen + Mit dem Webeditor bearbeiten Story-Beitrag erstellen Sie werden auf deiner Website als ein neuer Blogbeitrag veröffentlicht, damit deine Leserschaft nie etwas verpasst. Story-Beiträge verschwinden nicht @@ -1204,11 +1204,11 @@ Language: de Wähle aus der WordPress-Mediathek Zurück Erste Schritte - Folge Themen, um neue Blogs zu entdecken Von + Folge Themen, um neue Blogs zu entdecken + Als Spam markieren Dieser Referrer kann nicht als Spam markiert werden Spam-Markierung aufheben - Als Spam markieren Website öffnen Gif-Medien werden hochgeladen Archivmedien werden hochgeladen @@ -1225,11 +1225,11 @@ Language: de Classic Lässig Du musst der App die Berechtigung zur Audioaufzeichnung erteilen, um ein Video aufzunehmen - %s %s ausgewählt + %s + Mikrofon Anmeldelink per E-Mail erhalten Hmm, wir können kein WordPress.com-Konto finden, das mit dieser E-Mail-Adresse verknüpft ist. - Mikrofon Dieser Kommentar kann nicht angezeigt werden Artikel durchsuchen Diesen Beitrag melden @@ -1237,98 +1237,98 @@ Language: de Es ist ein interner Serverfehler aufgetreten Deine Aktion ist nicht zulässig %1$s weitere Elemente - Layout auswählen Hinweis: Das Spaltenlayout kann je nach Theme und Bildschirmgröße variieren - Erstelle einen Beitrag oder eine Story + Layout auswählen Eine Seite erstellen Einen Beitrag erstellen - Das könnte dir gefallen + Erstelle einen Beitrag oder eine Story Ausblenden - Videountertitel. Leer - Aktualisiert den Titel. - Block einfügen nach - Seitentitel. %s - Seitentitel. Leer - Beim Abspielen deines Videos ist ein Fehler aufgetreten - Dieses Gerät unterstützt die Camera2-API nicht. - Das Video konnte nicht gespeichert werden - Fehler beim Speichern des Bilds + Das könnte dir gefallen + Speicher anzeigen Operation läuft, versuche es erneut + Fehler beim Speichern des Bilds + Das Video konnte nicht gespeichert werden + Dieses Gerät unterstützt die Camera2-API nicht. + Beim Abspielen deines Videos ist ein Fehler aufgetreten + Seitentitel. Leer + Seitentitel. %s + Block einfügen nach + Aktualisiert den Titel. + Videountertitel. Leer Story-Slide wurde nicht gefunden - Speicher anzeigen - Die Story muss auf deinem Gerät gespeichert werden, bevor sie veröffentlicht werden kann. Überprüfe deine Speichereinstellungen und entferne Dateien, um Platz zu schaffen. Unzureichender Gerätespeicher + Verwalten + Die Story muss auf deinem Gerät gespeichert werden, bevor sie veröffentlicht werden kann. Überprüfe deine Speichereinstellungen und entferne Dateien, um Platz zu schaffen. Versuche erneut, die Slides zu speichern oder zu löschen und dann deine Story zu veröffentlichen. %1$d Slides konnten nicht gespeichert werden 1 Slide konnte nicht gespeichert werden - Verwalten %1$d Slides erfordern eine Aktion 1 Slide erfordert eine Aktion + „%1$s“ veröffentlicht „%1$s“ konnte nicht hochgeladen werden „%1$s“ konnte nicht hochgeladen werden - „%1$s“ veröffentlicht „%1$s“ wird hochgeladen … %1$d Slides verbleiben 1 Slide verbleibt mehrere Storys „%1$s“ wird gespeichert … - Ohne Titel + ausgewählt + nicht ausgewählt + fehlerhaft + Textausrichtung ändern + Textfarbe ändern Verwerfen + Löschen + Ohne Titel Dein Story-Beitrag wird nicht als Entwurf gespeichert. Story-Beitrag verwerfen? - Löschen Dieses Slide wurde noch nicht gespeichert. Wenn du diese Slide löschst, verlierst du alle deine vorgenommenen Änderungen. Dieses Slide wird aus deiner Story entfernt. Story-Slide entfernen? - Textfarbe ändern - Textausrichtung ändern - fehlerhaft - ausgewählt - nicht ausgewählt - Folie - Erneut versuchen + Vorschau + Text + Ton + Gespeichert + TEILEN + Erneut versuchen Gespeichert Schließen + Erneut versuchen + Seite erstellen + Leere Seite erstellen + Folie Teilen auf - TEILEN In Fotos gespeichert - Erneut versuchen - Gespeichert Wird gespeichert … Blitz Spiegeln - Ton - Text Sticker Blitz Kamera spiegeln Erfassen - Vorschau - Seite erstellen - Leere Seite erstellen Beginne mit der Auswahl eines der vielen vorgefertigten Seitenlayouts. Oder beginne einfach mit einer leeren Seite. - Layout auswählen Gib deiner Website einen Titel - Erstelle einen Beitrag oder eine Story - Erstelle einen Beitrag, eine Seite oder eine Story Tippe auf %1$s Erstellen. %2$s Wähle anschließend <b>Blogbeitrag</b> + Layout auswählen + Erstelle einen Beitrag, eine Seite oder eine Story + Erstelle einen Beitrag oder eine Story + Die Datei kann nicht hochgeladen werden.\nDas Speicherplatzkontingent wurde überschritten. + Speicherplatzkontingent überschritten Von Gerät auswählen Story-Beitrag Zum Bearbeiten von Website-Icons auf selbst gehosteten WordPress-Websites ist das Jetpack-Plugin erforderlich. Der verlinkte Seitensprung kann nicht gefunden werden - Die Datei kann nicht hochgeladen werden.\nDas Speicherplatzkontingent wurde überschritten. - Speicherplatzkontingent überschritten Datei hinzufügen Video ersetzen Bild oder Video ersetzen - Als Link konvertieren Video auswählen Bild oder Video auswählen Bild wählen Block entfernt - Gib deine bestehende Website-Adresse ein Registrierungsbestätigung Wenn du mit Google fortfährst und noch kein WordPress.com-Konto hast, erstellst du damit ein Konto und stimmst unseren %1$sGeschäftsbedingungen%2$s zu. + Gib deine bestehende Website-Adresse ein + Als Link konvertieren Wenn du fortfährst, stimmst du unseren %1$sGeschäftsbedingungen%2$s zu. Wir werden diese E-Mail-Adresse verwenden, um dein neues WordPress.com-Konto zu erstellen. Wir haben dir einen Anmeldelink per E-Mail gesendet, um dein neues WordPress.com-Konto zu erstellen. Überprüfe deine E-Mails auf diesem Gerät und tippe auf den Link in der E-Mail, die du von WordPress.com erhalten hast. @@ -1348,11 +1348,10 @@ Language: de Link per E-Mail senden Dein Passwort zurücksetzen Bei der Bearbeitung der Anfrage ist ein Problem aufgetreten. Bitte versuche es später erneut. - Prüfe deinen Website-Titel Tippe auf <b>%1$s</b>, um einen neuen Titel festzulegen. + Prüfe deinen Website-Titel Wenn dieser Beitrag in den Papierkorb verschoben wird, werden auch lokale Änderungen verworfen. Möchtest du wirklich fortfahren? %s Blockoptionen - Block entfernen Block duplizieren Block kopieren Kopierter Block @@ -1361,10 +1360,11 @@ Language: de Block wurde ausgeschnitten Block wurde kopiert Der Website-Titel kann nur von einem Benutzer mit Administratorrolle geändert werden. - Der Website-Titel wird in der Titelleiste eines Webbrowsers angezeigt und wird bei den meisten Themes im Header angezeigt. + Block entfernen + Ungespeicherte Änderungen Thema Konnte den Website-Titel nicht aktualisieren. Bitte überprüfe deine Netzwerkverbindung und versuche es erneut. - Ungespeicherte Änderungen + Der Website-Titel wird in der Titelleiste eines Webbrowsers angezeigt und wird bei den meisten Themes im Header angezeigt. Link in einem Browser öffnen Navigiert zum vorherigen Content Sheet Navigiert zum Anpassen des Verlaufs @@ -1378,104 +1378,104 @@ Language: de Inhaltliche Struktur Jeder Ich - Verwerfen Nicht festgelegt - Schlagwörter helfen den Lesern zu verstehen, worum es in einem Beitrag geht. - Veröffentlichungsdatum - Schlagwörter hinzufügen - Zurück - Jetzt speichern - Jetzt einreichen - Jetzt planen - Veröffentlichen in + Verwerfen + Abbrechen Schlagwörter + Veröffentlichen in + Jetzt planen + Jetzt einreichen + Jetzt speichern + Zurück + Schlagwörter hinzufügen + Schlagwörter helfen den Lesern zu verstehen, worum es in einem Beitrag geht. Veröffentlichungsdatum - Abbrechen In Entwurf verschieben Beiträge im Papierkorb können nicht bearbeitet werden. Möchtest du den Status dieses Beitrags in \"Entwurf\" ändern, damit du ihn bearbeiten kannst? + Veröffentlichungsdatum + Veröffentlichungsdatum + Geplant + Im Papierkorb + Veröffentlicht Beitrag zu \"Entwürfe\" verschieben? - Wähle deine Themen - Wähle deine Themen Fertig Wähle ein paar aus, um fortzufahren - Veröffentlicht - Im Papierkorb - Geplant - Veröffentlichungsdatum CCPA-Datenschutzhinweis lesen Nach dem California Consumer Privacy Act („CCPA“) sind wir verpflichtet, den Einwohnern Kaliforniens zusätzliche Informationen zu den Kategorien personenbezogener Daten mitzuteilen, die wir sammeln und weitergeben. Außerdem müssen wir Auskunft darüber erteilen, woher wir diese personenbezogenen Daten erhalten und wie und warum wir sie verwenden. - Datenschutzhinweis für Benutzer in Kalifornien - Status und Sichtbarkeit + Wähle deine Themen + Wähle deine Themen Jetzt aktualisieren + Status und Sichtbarkeit + Datenschutzhinweis für Benutzer in Kalifornien Öffne das Menü mit den Blockaktionen Nach oben verschieben Erwähnung einfügen - Zum Öffnen des Bottom Sheets mit den verfügbaren Optionen zweimal tippen Zum Öffnen des Action Sheets mit den verfügbaren Optionen zweimal tippen - Wir können die Seiten momentan nicht öffnen. Bitte versuche es später erneut - Als Beitragsseite festlegen - Als Homepage festlegen - %1$s ist kein gültiger %2$s + Zum Öffnen des Bottom Sheets mit den verfügbaren Optionen zweimal tippen + Klassischer Blog Seite auswählen Beitragsseite - Statische Seite - Klassischer Blog + Als Homepage festlegen + Als Beitragsseite festlegen Die ausgewählte Homepage und die Seite für Beiträge können nicht identisch sein. - Aktualisierung der Homepage-Einstellungen fehlgeschlagen, überprüfe deine Internetverbindung - Homepage-Einstellungen können nicht gespeichert werden, bevor die Seiten geladen werden - Homepage-Einstellungen können nicht gespeichert werden + Wir können die Seiten momentan nicht öffnen. Bitte versuche es später erneut + Statische Seite + %1$s ist kein gültiger %2$s + Homepage-Einstellungen Akzeptieren + Homepage-Einstellungen können nicht gespeichert werden + Homepage-Einstellungen können nicht gespeichert werden, bevor die Seiten geladen werden + Aktualisierung der Homepage-Einstellungen fehlgeschlagen, überprüfe deine Internetverbindung Laden von Seiten fehlgeschlagen Wähle eine Homepage, die deine neuesten Beiträge anzeigt (klassischer Blog), oder eine feste/statische Seite. - Homepage-Einstellungen Homepage - Aktualisierung der Beitragsseite fehlgeschlagen + Homepage wurde erfolgreich aktualisiert Beitragsseite wurde erfolgreich aktualisiert Aktualisierung der Homepage fehlgeschlagen - Homepage wurde erfolgreich aktualisiert Um eine Beitragsseite festzulegen, aktiviere „Statische Seite“ in den Website-Einstellungen Um eine Homepage festzulegen, aktiviere „Statische Seite“ in den Website-Einstellungen + Aktualisierung der Beitragsseite fehlgeschlagen Wähle eine Farbe aus Zum Wechseln zu den Farbeinstellungen zweimal tippen Wenn du Websites folgst, wirst du ihren Inhalt hier sehen - Mehr erfahren - Was ist neu in %s? - %d einfügen zuschneiden - Laden in die Datei fehlgeschlagen, bitte versuche es erneut. - Vorschau des Vorschaubilds - Diese Medien verwenden + %d einfügen Dieses Video verwenden - Medien auswählen + Diese Medien verwenden Video auswählen + Medien auswählen Die Website konnte nicht ausgewählt werden. Bitte versuche es erneut. - Weiter - Rebloggen ist fehlgeschlagen - Websites verwalten - Sobald du eine Website bei WordPress.com erstellt hast, kannst du Inhalte, die dir gefallen, auf deiner eigenen Website rebloggen. - Keine verfügbaren Websites bei WordPress.com + Mehr erfahren + Vorschau des Vorschaubilds + Laden in die Datei fehlgeschlagen, bitte versuche es erneut. + Was ist neu in %s? + Kopieren + Einfügen Was ist neu? + Keine verfügbaren Websites bei WordPress.com Link-Adresse wurde kopiert Link-Adresse kopieren Teilen über Teilen nicht möglich - Einfügen Weiter - Kopieren + Weiter + Rebloggen ist fehlgeschlagen + Websites verwalten + Sobald du eine Website bei WordPress.com erstellt hast, kannst du Inhalte, die dir gefallen, auf deiner eigenen Website rebloggen. Anzahl an Spalten - Block von Position %1$s nach rechts zur Position %2$s verschieben Block nach rechts verschieben - Block von Position %1$s nach links zur Position %2$s verschieben Block nach links verschieben Zum Verschieben des Blocks nach rechts zweimal tippen Zum Verschieben des Blocks nach links zweimal tippen - Blockeinstellungen + Block von Position %1$s nach rechts zur Position %2$s verschieben + Block von Position %1$s nach links zur Position %2$s verschieben Das Dashboard wird erstellt Das Theme wird eingerichtet Die Website-Funktionen werden hinzugefügt Die Website-URL wird abgerufen Deine Website wird in Kürze bereit sein Hurra!\nFast geschafft + Blockeinstellungen Upload abbrechen Beim Verarbeiten der Anfrage ist ein Problem aufgetreten Bereitgestellt von Tenor @@ -1490,12 +1490,12 @@ Language: de Auf den Inhalt einer privaten Website konnte nicht zugegriffen werden. Einige Medien sind möglicherweise nicht verfügbar. Auf den Inhalt einer privaten Website wird zugegriffen Das Bild konnte nicht zugeschnitten und gespeichert werden, bitte versuche es erneut. - Das Laden des Bildes ist fehlgeschlagen.\nBitte tippe, um es erneut zu versuchen. Vorschaubild Unbekanntes Seitenformat Wir konnten diese Aktion nicht abschließen und haben diese Seite nicht zur Überprüfung gesendet. Wir konnten diese Aktion nicht abschließen und haben diese Seite nicht geplant. Wir konnten diese Aktion nicht abschließen und haben diese private Seite nicht veröffentlicht. + Das Laden des Bildes ist fehlgeschlagen.\nBitte tippe, um es erneut zu versuchen. Wir konnten diese Aktion nicht abschließen und haben diese Seite nicht veröffentlicht. Wir konnten diese Seite nicht zur Überprüfung senden, versuchen es aber später erneut. Wir konnten diese Seite nicht planen, versuchen es aber später erneut. @@ -1507,134 +1507,134 @@ Language: de Wir konnten diese Medien nicht hochladen und haben diese Seite nicht veröffentlicht. Wir werden deinen Entwurf speichern, wenn dein Gerät wieder online ist Wir werden deine private Seite veröffentlichen, wenn dein Gerät wieder online ist. - Wir werden deine Seite planen, wenn dein Gerät wieder online ist. - Wir werden deine Seite zur Überprüfung senden, wenn dein Gerät wieder online ist. - Wir werden die Seite veröffentlichen, wenn dein Gerät wieder online ist. Seite in Warteschlange Seite wird hochgeladen + Wir werden die Seite veröffentlichen, wenn dein Gerät wieder online ist. + Wir werden deine Seite planen, wenn dein Gerät wieder online ist. + Wir werden deine Seite zur Überprüfung senden, wenn dein Gerät wieder online ist. Das Gerät ist offline. Die Seite wurde lokal gespeichert. Du hast nicht gespeicherte Änderungen an dieser Seite vorgenommen - Deine Seite wird hochgeladen - Es befinden sich nicht fertiggestellte Medien-Uploads in der Seite; sie wurde lokal gespeichert. - Die Seite wurde auf dem Gerät gespeichert - Die Seite wurde online gespeichert - Blog für QuickPress-Tastenkombination auswählen - Festgelegt durch Batterieschoner - Dunkel - Hell - Design Du hast vor kurzem Änderungen an dieser Seite vorgenommen, diese aber nicht gespeichert. Wähle eine Version aus, die geladen wird:\n\n + Design + Hell + Dunkel + Festgelegt durch Batterieschoner + Blog für QuickPress-Tastenkombination auswählen + Die Seite wurde online gespeichert + Die Seite wurde auf dem Gerät gespeichert + Es befinden sich nicht fertiggestellte Medien-Uploads in der Seite; sie wurde lokal gespeichert. + Deine Seite wird hochgeladen Beitragsinhalt anzeigen - Nur Textauszug anzeigen Link zu + Nur Textauszug anzeigen Link-Einstellungen - Länge des Textauszugs (in Wörtern) Covermedien bearbeiten - ANPASSEN + Länge des Textauszugs (in Wörtern) Button-Link-URL - Rahmenradius + ANPASSEN Absatz-Block hinzufügen + Rahmenradius Erstelle einen Beitrag Im Papierkorb Geplant Veröffentlicht - Die Facebook-Verbindung findet keine Seiten. Jetpack Social kann keine Verbindung zu Facebook-Profilen herstellen, nur zu öffentlichen Seiten. Nicht verbunden - Likes - Follows - Kommentare + Die Facebook-Verbindung findet keine Seiten. Jetpack Social kann keine Verbindung zu Facebook-Profilen herstellen, nur zu öffentlichen Seiten. Ungelesen - Nicht löschen Papierkorb + Nicht löschen + Kommentare + Likes + Follows Aktivität Beiträge und Seiten Allgemein Neue Karte hinzufügen Neue Statistikkarte hinzufügen - Verwende den Filter-Button, um Beiträge zu bestimmten Themen zu finden Wähle ein Schlagwort oder eine Website, ein Popup-Fenster aus - Wähle eine Website oder ein Schlagwort aus, um Beiträge zu filtern Entferne den aktuellen Filter - Themen und Websites verwalten Melde dich bei WordPress.com an - Melde dich bei WordPress.com an, um die neuesten Beiträge zu Themen zu sehen, denen du folgst + Wähle eine Website oder ein Schlagwort aus, um Beiträge zu filtern + Verwende den Filter-Button, um Beiträge zu bestimmten Themen zu finden + Themen und Websites verwalten Melde dich bei WordPress.com an, um die neuesten Beiträge von Websites zu sehen, denen du folgst + Melde dich bei WordPress.com an, um die neuesten Beiträge zu Themen zu sehen, denen du folgst + Block dahinter hinzufügen + Block davor hinzufügen Aktuellen Block ersetzen - Am Ende hinzufügen Am Anfang hinzufügen - Block davor hinzufügen - Block dahinter hinzufügen - Ein Thema hinzufügen + Am Ende hinzufügen Einer Website folgen - Du kannst Beiträgen zu einem bestimmten Thema folgen, indem du ein Thema hinzufügst Die neuesten Beiträge von Websites anzeigen, denen du folgst - Folgen + Ein Thema hinzufügen + Du kannst Beiträgen zu einem bestimmten Thema folgen, indem du ein Thema hinzufügst Filter - Videountertitel. %s + Folgen Video bearbeiten + Videountertitel. %s Medien bearbeiten Füge einen Shortcode hinzu… Beitragsautor Einen Beitrag erstellen - Du kennst nun alle Statistiken für diesen Zeitraum.\n Tippe erneut, um von vorne zu beginnen. Es gibt keine Statistiken für diesen Zeitraum. Beitragsaktivität für %1$s +   & %1$d %2$s + niedrig + mittel + hoch + sehr hoch + Du kennst nun alle Statistiken für diesen Zeitraum.\n Tippe erneut, um von vorne zu beginnen. Tage mit %1$s Aufrufen von %2$s: %2$s %3$s.Tippe für weitere Informationen. Navigiere zu allen Statistiken für diesen Zeitraum - sehr hoch - hoch - mittel - niedrig -   & %1$d %2$s %1$s, %2$d %3$s Bildunterschrift der Galerie. %s Seite oder Beitrag erstellen - Ersteller der Website Nicht jetzt + Ersteller der Website Was immer du erstellen oder teilen möchtest, wir helfen dir dabei, es genau hier zu tun. - Willkommen bei WordPress Foto-Bibliothek + Willkommen bei WordPress Bild nicht ausgewählt + Blogbeitrag Ausgewählt Bild ausgewählt Vorschaubild - Blogbeitrag Erstellen Veröffentlichen Jetzt synchronisieren - Dieser Beitrag wird umgehend synchronisiert. Bereit für die Synchronisation? - Diese Domain ist nicht verfügbar + Dieser Beitrag wird umgehend synchronisiert. -%s + Diese Domain ist nicht verfügbar Wir konnten nicht auf deine Website zugreifen. Du musst dich an deinen Host wenden, um dies zu beheben. Wir konnten wegen eines Problems mit dem <b>SSL-Zertifikat</b> nicht auf deine Website zugreifen. Du musst dich an deinen Host wenden, um dies zu beheben. Wir konnten nicht auf deine Website zugreifen, da <b>HTTP-Authentifizierung</b> erforderlich ist. Du musst dich an deinen Host wenden, um dies zu beheben. - Wir konnten nicht auf die <b>XMLRPC-Datei</b> deiner Website zugreifen. Du musst dich an deinen Host wenden, um dies zu beheben. + Folgen Fast geschafft! Wir müssen nur noch deine mit Jetpack verbundene E-Mail-Adresse bestätigen <b>%1$s</b> Mit deinen Anmeldedaten der Website %1$s anmelden + Wir konnten nicht auf die <b>XMLRPC-Datei</b> deiner Website zugreifen. Du musst dich an deinen Host wenden, um dies zu beheben. Website-Seite - Folgen - Likes - Entdecken Gespeichert - Themen Websites - %sQi - %sQa - %sT + Entdecken + Likes + %sk %sB %sM - %sk + %sQa + %sT + %sQi Wir können die Beiträge momentan nicht öffnen. Bitte versuche es später erneut Wir können die Daten deiner Website momentan nicht laden. Bitte versuche es später erneut + Themen WordPress-Mediathek - Nicht unterstützt Gruppierung aufheben + Nicht unterstützt + Ein Foto aufnehmen + Ein Foto oder Video aufnehmen + Ein Video aufnehmen Zum Ausblenden der Tastatur hier tippen Zum Anzeigen der Hilfe hier tippen - Ein Video aufnehmen - Ein Foto oder Video aufnehmen - Ein Foto aufnehmen Fang an zu schreiben… Block %s. Dieser Block hat ungültigen Inhalt Block %s. Leer @@ -1648,16 +1648,16 @@ Language: de Einstellungen öffnen Diese Anfrage kann von keiner Anwendung verarbeitet werden. Installiere bitte einen Webbrowser. Nach oben - Block von Zeile %1$s nach oben in Zeile %2$s verschieben Block nach oben verschieben Block von Zeile %1$s nach unten in Zeile %2$s verschieben + Block von Zeile %1$s nach oben in Zeile %2$s verschieben Block nach unten verschieben - Linktext Link eingefügt Bildunterschrift. %s Tastatur ausblenden Hilfe-Icon Zum Rückgängigmachen der letzten Änderung zweimal tippen + Linktext Zum Umschalten der Einstellung zweimal tippen Zum Auswählen eines Bilds zweimal tippen Zum Auswählen eines Videos zweimal tippen @@ -1674,25 +1674,25 @@ Language: de Alt-Text VIDEO HINZUFÜGEN URL hinzufügen - Alt-Text hinzufügen BILD ODER VIDEO HINZUFÜGEN BILD HINZUFÜGEN HIER BLOCK HINZUFÜGEN - Tippe auf den Button „Hinzufügen, um Beiträge zu speichern“, um einen Beitrag in deiner Liste zu speichern. + Alt-Text hinzufügen „Die Liste wurde mit %1$d Einträgen geladen.“ + Tippe auf den Button „Hinzufügen, um Beiträge zu speichern“, um einen Beitrag in deiner Liste zu speichern. Benachrichtigungen - Deaktiviert - Aktiviert Wenn du die Benachrichtigungen für diese Website deaktivierst, wird auch die Benachrichtigungsanzeige auf dem Tab „Benachrichtigungen“ für diese Website deaktiviert. Du kannst detailliert festlegen, welche Art von Benachrichtigung du siehst, nachdem du die Benachrichtigungen für diese Website aktiviert hast. - Aktiviere die Benachrichtigungen für diese Website, um Benachrichtigungen auf dem Tab „Benachrichtigungen“ zu sehen. - Benachrichtigungsanzeige auf dem Tab „Benachrichtigungen“ für diese Website aktivieren - Benachrichtigungsanzeige auf dem Tab „Benachrichtigungen“ für diese Website deaktivieren - Benachrichtigungen für diese Website + Aktiviert + Deaktiviert Benachrichtigungen für diese Website + Benachrichtigungen für diese Website + Benachrichtigungsanzeige auf dem Tab „Benachrichtigungen“ für diese Website deaktivieren + Benachrichtigungsanzeige auf dem Tab „Benachrichtigungen“ für diese Website aktivieren + Aktiviere die Benachrichtigungen für diese Website, um Benachrichtigungen auf dem Tab „Benachrichtigungen“ zu sehen. Bild oder Video hinzufügen Wir konnten diesen Beitrag nicht zur Überprüfung einreichen, aber wir werden es später erneut versuchen. - Wir konnten diesen Beitrag nicht planen, aber wir werden es später erneut versuchen. Wir konnten diesen privaten Beitrag nicht veröffentlichen, aber wir werden es später erneut versuchen. + Wir konnten diesen Beitrag nicht planen, aber wir werden es später erneut versuchen. Wir konnten diesen Beitrag nicht veröffentlichen, aber wir werden es später erneut versuchen. Wir konnten diese Aktion nicht abschließen und haben diesen Beitrag nicht zur Überprüfung eingereicht. Wir konnten diese Aktion nicht abschließen und haben diesen Beitrag nicht geplant. @@ -1711,15 +1711,15 @@ Language: de Vorschau nicht verfügbar Fehler beim Versuch, Den Beitrag vor der Vorschau zu speichern Vorschau wird generiert… - Wird gespeichert … Sie haben nicht gespeicherte Änderungen an diesem Beitrag vorgenommen + Wird gespeichert … Die Version dieser App Die Version von einem anderen Gerät - Von dieser App\nGespeichert auf %1$s\n\nVon einem anderen Gerät\nGespeichert auf %2$s\n Sie haben kürzlich Änderungen an diesem Beitrag vorgenommen, aber nicht gespeichert. Wählen Sie eine zu ladende Version aus:\n\n Welche Version möchten Sie bearbeiten? - Endgültig löschen Wir speichern nicht die neuesten Änderungen an Ihrem Entwurf. + Von dieser App\nGespeichert auf %1$s\n\nVon einem anderen Gerät\nGespeichert auf %2$s\n + Endgültig löschen Wir werden diese Änderungen nicht planen. Wir werden diese Änderungen nicht zur Überprüfung einreichen. Wir werden diese Änderungen nicht veröffentlichen. @@ -1740,13 +1740,13 @@ Language: de Mehr Ersetze die integrierte WordPress-Suche durch eine verbesserte Suchfunktion Verbesserte Suche - Jetpack-Suche Werbefreies Videohosting Medien Lade Seiten schneller, indem du Jetpack erlaubst, deine Bild- und statischen Dateien wie CSS und JavaScript zu optimieren. Schnellere statische Dateien Schnellere Bilder Aus + Jetpack-Suche Ein Website-Beschleuniger Verbessere die Ladezeit deiner Website, indem du nur die auf dem Bildschirm sichtbaren Bilder lädst. @@ -1761,45 +1761,45 @@ Language: de Desktop Standard Dialog schließen - Vorschautyp auswählen - Teilen + „%s“ wird in 10 Minuten veröffentlicht Zurück gehen Vorwärts gehen - „%1$s“ ist für die Veröffentlichung auf „%2$s“ in deiner %3$s-App geplant \n %4$s + Teilen + Vorschautyp auswählen Von WordPress geplanter Beitrag: „%s“ - „%s“ wird in 10 Minuten veröffentlicht + „%1$s“ ist für die Veröffentlichung auf „%2$s“ in deiner %3$s-App geplant \n %4$s + Wenn veröffentlicht „%s“ wird in 1 Stunde veröffentlicht „%s“ wurde veröffentlicht Geplanter Beitrag: 10-Minuten-Erinnerung Geplanter Beitrag: 1-Stunde-Erinnerung Geplanter Beitrag Es kann keine Benachrichtigung erstellt werden, wenn das Datum der Veröffentlichung in der Vergangenheit liegt. - Wenn veröffentlicht - Vor 10 Minuten Vor 1 Stunde + Vor 10 Minuten Aus Zu Kalender hinzufügen Benachrichtigung Datum und Uhrzeit Bitte gib eine vollständige Website-Adresse ein, wie z.&nbsp;B. example.com. - Meld dich mit WordPress.com an, um dich mit %1$s zu verbinden. - Aufrufe - Beitrag %1$s: %2$s, %3$s: %4$s + Beitrag Element ist zusammengeklappt Element ist aufgeklappt Zuklappen Aufklappen Diagramm aktualisiert. - %1$s %2$s für die Periode: %3$s, Veränderung gegenüber der Vorperiode - %4$s + Meld dich mit WordPress.com an, um dich mit %1$s zu verbinden. Laden der ausgewählten Kartendaten Editor + %1$s %2$s für die Periode: %3$s, Veränderung gegenüber der Vorperiode - %4$s + Aufrufe Erweitern Einklappen Prüfe deinen Posteingang – eine Anleitung wurde an deine E-Mail-Adresse gesendet Prüfe deinen Posteingang – eine Anleitung wurde an %s gesendet - Abbrechen OK + Abbrechen http(s):// Link entfernen Link einfügen @@ -1807,41 +1807,41 @@ Language: de Medien werden hochgeladen.\nFür Optionen bitte hier tippen. Link in neuem Fenster/Tab öffnen Um deine Statistiken anzuzeigen, melde dich beim WordPress.com-Konto an. + Auf einen Blick + Heute + Hier finden dich andere im Internet. Es gibt keine Beiträge, die deiner Suche entsprechen + Gesamter Zeitraum Beiträge durchsuchen - Hier finden dich andere im Internet. Wähle einen Premium-Domainnamen Alle Tarife auf WordPress.com enthalten einen individuellen Domainnamen. Registriere dir jetzt deine kostenlose Domain. - Auf einen Blick - Heute - Gesamter Zeitraum - Aufrufe diese Woche - Bitte melde dich an, um ein Widget hinzuzufügen. - Kein Netzwerk verfügbar - Daten konnten nicht geladen werden - Art - Farbe - Wähle deine Website Dunkel Hell - Farbe - Wähle deine Website + Farbe + Art + Kein Netzwerk verfügbar + Daten konnten nicht geladen werden + Aufrufe diese Woche Website - Gesamter Zeitraum + Wähle deine Website + Farbe Aufrufe dieser Woche Widget hinzufügen + Gesamter Zeitraum + Bitte melde dich an, um ein Widget hinzuzufügen. + Wähle deine Website Es dauert länger als üblich, die Details des Plugins zu aktualisieren. Bitte versuche es später errneut. Falls du kürzlich einen Domainnamen registriert hast, warte bitte ab, bis diese fertig eingerichtet ist und versuche es erneut.\n\nFalls nicht, scheint etwas schiefgegangen zu sein und die Plugin-Funktion ist möglicherweise für diese Website nicht verfügbar. + Mit der Einrichtung von Jetpack erklärst du dich mit unseren %1$sBestimmungen und Konditionen%2$s einverstanden. + Die Einstellungen konnten nicht abgerufen werden: Einige APIs sind für diese OAuth-App-ID + Konto-Kombination nicht verfügbar. + Diese Seite kann gerade nicht geladen werden. + Prüfe deine Netzwerkverbindung und versuche es erneut. Status (nicht verfügbar) Mit der Registrierung dieser Domain stimmst du unseren %1$sBestimmungen und Konditionen%2$s zu - Prüfe deine Netzwerkverbindung und versuche es erneut. - Diese Seite kann gerade nicht geladen werden. - Die Einstellungen konnten nicht abgerufen werden: Einige APIs sind für diese OAuth-App-ID + Konto-Kombination nicht verfügbar. - Mit der Einrichtung von Jetpack erklärst du dich mit unseren %1$sBestimmungen und Konditionen%2$s einverstanden. - Keine Verbindung. Die Bearbeitung ist deaktiviert. - Um die App wieder mit deiner selbst gehosteten Website zu verbinden, gib hier das neue Passwort der Website ein. - Passwort aktualisiert Passwort aktualisieren + Passwort aktualisiert + Um die App wieder mit deiner selbst gehosteten Website zu verbinden, gib hier das neue Passwort der Website ein. + Keine Verbindung. Die Bearbeitung ist deaktiviert. Domainname wird registriert … Bundesstaat auswählen Land wählen @@ -1868,12 +1868,12 @@ Language: de Wähle aus, welche Statistiken du sehen möchtest, und konzentriere dich auf die Daten, die für dich am Wichtigsten sind. Tippe unten in Einsichten auf %1$s, um deine Statistiken anzupassen. Deine Statistiken verwalten Revisionen werden abgerufen… + Dein Entwurf wird hochgeladen Medien hochladen fehlgeschlagen.\nBitte tippen für Optionen. Medien einfügen fehlgeschlagen.\nBitte tippen für neuen Versuch. - Dein Entwurf wird hochgeladen Entwurf wird hochgeladen - Entwürfe Beim Wiederherstellen des Beitrags ist ein Fehler aufgetreten. + Entwürfe Zurückdatiert auf: %s Zeige nur die relevantesten Statistiken an. Füge deine Einsichten unten hinzu und organisiere sie. Social Media @@ -1891,8 +1891,8 @@ Language: de Beitrag wird wiederhergestellt Beitrag wiederhergestellt Beitrag wird in den Papierkorb verschoben - Wenn dieser Beitrag in den Papierkorb verschoben wird, werden ungespeicherte Änderungen verworfen. Bist du sicher, dass du fortfahren möchtest? Lokale Änderungen + Wenn dieser Beitrag in den Papierkorb verschoben wird, werden ungespeicherte Änderungen verworfen. Bist du sicher, dass du fortfahren möchtest? In Entwurf verschieben Zur Listenansicht wechseln Zur Kartenansicht wechseln @@ -1902,32 +1902,32 @@ Language: de Du hast noch keine Beiträge veröffentlicht Bitte mit deinem Benutzernamen und Passwort anmelden. Bitte mit deinem WordPress.com-Benutzernamen anstelle deiner E-Mail-Adresse anmelden. - Durchschn. Wörter/Beitrag + Jahr + Dieses Jahr + Beiträge Wörter insgesamt - Durchschn. Likes/Beitrag Likes insgesamt - Durchschn. Kommentare/Beitrag Kommentare insgesamt - Beiträge - Jahr - Dieses Jahr + Durchschn. Wörter/Beitrag + Durchschn. Likes/Beitrag + Durchschn. Kommentare/Beitrag Die Website unter dieser Adresse ist keine WordPress-Website. Um sie verbinden zu können, muss sie WordPress-Website benutzen. - Die Überprüfung des verfügbaren Domain-Guthabens konnte nicht durchgeführt werden Überprüfen von Domain-Guthaben - Domain registrieren - Um Plugins zu installieren, benötigst du eine individuelle Domain, die deiner Website zugeordnet ist. + Die Überprüfung des verfügbaren Domain-Guthabens konnte nicht durchgeführt werden Plugin installieren - Du kannst das Erscheinungsbild deiner Website später anpassen + Um Plugins zu installieren, benötigst du eine individuelle Domain, die deiner Website zugeordnet ist. + Domain registrieren + Veröffentlicht am: %s + Durchschnittliche Aufrufe pro Tag + Monate und Jahre + Mehr laden + Ansichten Veröffentlichen auf: %s Planen für: %s - Veröffentlicht am: %s Geplant für: %s Letzte Wochen - Durchschnittliche Aufrufe pro Tag - Ansichten Zeitraum - Monate und Jahre - Mehr laden + Du kannst das Erscheinungsbild deiner Website später anpassen Heute Beste Uhrzeit Bester Tag @@ -1942,76 +1942,81 @@ Language: de Mehr Beiträge Weniger Beiträge Du kannst deinen Fortschritt verlieren. Bist du sicher, dass du abbrechen willst? - Tarife trotzdem ansehen - Für die Ansicht der Tarife ist eine Internetverbindung erforderlich, sodass Details möglicherweise nicht mehr aktuell sind. Für die Ansicht der Tarife ist eine Internetverbindung erforderlich. + Für die Ansicht der Tarife ist eine Internetverbindung erforderlich, sodass Details möglicherweise nicht mehr aktuell sind. + Tarife trotzdem ansehen Wir können momentan keine Tarife laden. Bitte versuche es später erneut. - Tarife können nicht geladen werden - Keine Verbindung + Block-Editor benutzen + Bearbeite neue Beiträge und Seiten mit dem Block-Editor. + Daten nicht geladen Zum Block-Editor wechseln + Keine Verbindung Beim Laden deiner Daten ist ein Problem aufgetreten. Aktualisiere deine Seite, um es erneut zu versuchen. - Daten nicht geladen - Bearbeite neue Beiträge und Seiten mit dem Block-Editor. - Block-Editor benutzen + Tarife können nicht geladen werden beenden + Nächste Schritte + Deine Besucher sehen dein Symbol in ihrem Browser. Füge ein individuelles Symbol hinzu, um einen eleganten, professionellen Look zu erhalten. Vergrößere deine Reichweite Passe deine Website an - Nächste Schritte Wähle ein einzigartiges Website-Icon aus - Deine Besucher sehen dein Symbol in ihrem Browser. Füge ein individuelles Symbol hinzu, um einen eleganten, professionellen Look zu erhalten. - Wähle %1$s Statistiken %2$s aus, um zu sehen, wie deine Website funktioniert. Tippe auf %1$s Dein Website-Icon %2$s, um ein neues hochzuladen. Entwirf und veröffentliche einen Beitrag. + Wähle %1$s Statistiken %2$s aus, um zu sehen, wie deine Website funktioniert. Teilen der Beiträge aktivieren Neue Beiträge automatisch für deine Social-Media-Konten freigeben. Die Statistiken deiner Website überprüfen - Bleib auf dem Laufenden über die Leistung deiner Website. Das Entfernen der nächsten Schritte blendet alle Touren auf dieser Seite aus. Diese Aktion kann nicht rückgängig gemacht werden. Nächste Schritte entfernen Das entfernen - Aufgabe überspringen + Bleib auf dem Laufenden über die Leistung deiner Website. Erinnerung + Aufgabe überspringen Nächsten Zeitraum auswählen Vorherigen Zeitraum auswählen - %1$s der Aufrufe Beliebteste Zeit %1$s (%2$s) +%1$s (%2$s) - Vorschau der Website anzeigen - Löschen - Es scheint, als ob du eine langsame Verbindung hast. Wenn du deine neue Website nicht in der Liste siehst, versuch sie zu aktualisieren. - Assistent zum Erstellen von Websites abbrechen + %1$s der Aufrufe + Hier wirst du im Internet gefunden. + Website erstellen + Website erstellen Wir erstellen deine neue Website. + Assistent zum Erstellen von Websites abbrechen + Es scheint, als ob du eine langsame Verbindung hast. Wenn du deine neue Website nicht in der Liste siehst, versuch sie zu aktualisieren. + Löschen + Vorschau der Website anzeigen Es ist ein Problem aufgetreten - Website erstellen - Website erstellen - Hier wirst du im Internet gefunden. Keine verfügbaren Adressen, die deiner Suche entsprechen. Fehler bei der Kommunikation mit dem Server, bitte versuche es erneut. Es ist ein Problem aufgetreten Es ist ein Problem aufgetreten - Deine Website wurde erstellt! %1$d von %2$d - Website erstellen - Vorschläge aktualisiert - Es konnte keine neu hinzugefügte, selbst gehostete Website ausgewählt werden. Versionskonflikt - Automatische Absturzberichte zulassen, die uns helfen, die Leistung der App zu verbessern. - Absturzberichte - Widerrufen - Web-Version verworfen - Lokale Version verworfen - Aktualisieren des Beitrags + Es konnte keine neu hinzugefügte, selbst gehostete Website ausgewählt werden. + Vorschläge aktualisiert + Website erstellen + Deine Website wurde erstellt! Web verwerfen + Aktualisieren des Beitrags + Lokale Version verworfen + Web-Version verworfen + Widerrufen + Absturzberichte + Automatische Absturzberichte zulassen, die uns helfen, die Leistung der App zu verbessern. + Lösen des Synchronisierungskonflikts. + Dieser Beitrag hat zwei Versionen, die im Konflikt stehen. Wähle die Version aus, die du verwerfen möchtest.\n\n Lokal verwerfen Lokal\nGespeichert auf %1$s\n\nWeb\nGespeichert auf %2$s\n - Dieser Beitrag hat zwei Versionen, die im Konflikt stehen. Wähle die Version aus, die du verwerfen möchtest.\n\n - Lösen des Synchronisierungskonflikts. Keine Daten für diesen Zeitraum Positionsangabe von Medien entfernen Wir können die Statistiken momentan nicht öffnen. Bitte versuche es später erneut + Path + LinkedIn + Google+ + Tumblr + Twitter + Facebook Keine Medien entsprechen deiner Suche - Suche, um GIFs zu finden und sie zu deiner Mediathek hinzuzufügen! Aufrufe Autor Autoren @@ -2031,23 +2036,20 @@ Language: de Referrer Referrer Beiträge und Seiten - Path - LinkedIn - Google+ - Tumblr - Twitter - Facebook Mehr anzeigen Beitrag teilen Beitrag erstellen %2$s wurde vor %1$s veröffentlicht. Hier siehst du, wie der Beitrag bislang abschneidet: - %2$s wurde vor %1$s veröffentlicht. Erhalte mehr Aufrufe deines Beitrags, indem du ihn teilst: + Suche, um GIFs zu finden und sie zu deiner Mediathek hinzuzufügen! Schlagwörter und Kategorien + %2$s wurde vor %1$s veröffentlicht. Erhalte mehr Aufrufe deines Beitrags, indem du ihn teilst: Gesamte Zeit %1$s - %2$s Follower - Dienst %1$s | %2$s + E-Mail + WordPress.com + Dienst Aufrufe Titel Aufrufe @@ -2060,8 +2062,6 @@ Language: de Seit Follower %1$s-Follower insgesamt: %2$s - E-Mail - WordPress.com Einsichten verwalten Noch keine Einsichten hinzugefügt Noch keine Daten @@ -2088,11 +2088,11 @@ Language: de Wenn du Änderungen an deiner Website vornimmst, kann du hier deinen Verlauf sehen Wenn du Änderungen an deiner Seite vornimmst, kann du hier deinen Verlauf sehen Benutzer-Avatar - Vollbild Groß + Verlauf + Vollbild Mittelgroß Vorschaubild - Verlauf Die ausgewählte Seite ist nicht verfügbar Ausstehender Review Du hast keine Seiten im Papierkorb @@ -2101,9 +2101,9 @@ Language: de Du hast noch keine Seiten veröffentlicht Seiten suchen Keine Seiten entsprechen deiner Suche - Endgültig löschen In Papierkorb verschieben In Entwurf verschieben + Endgültig löschen Übergeordnete Seite festlegen Anzeigen Im Papierkorb @@ -2131,11 +2131,11 @@ Language: de Website einrichten. Fühlt es sich nicht gut an, Dinge von einer Liste zu streichen? Deine Website ansehen - Zeige eine Vorschau deiner Website an, um zu sehen, wie sie deinen Besuchern angezeigt wird. Website teilen Tippe auf %1$s Teilen %2$s, um fortzufahren - Tippe auf die %1$s Verbindungen %2$s, um deine Social-Media-Konten hinzuzufügen Verknüpfe deine Social Media-Konten, sodass deine Website automatisch neue Beiträge teilt. + Tippe auf die %1$s Verbindungen %2$s, um deine Social-Media-Konten hinzuzufügen + Zeige eine Vorschau deiner Website an, um zu sehen, wie sie deinen Besuchern angezeigt wird. Beitrag veröffentlichen Tippe auf %1$s Beitrag erstellen %2$s, um einen neuen Beitrag zu erstellen Nein, danke @@ -2143,8 +2143,8 @@ Language: de Los Abbrechen Später - Mehr Du hast keine Websites + Mehr Keine abonnierten Themen Füge hier Themen hinzu, um Beiträge zu deinen Lieblingsthemen zu finden Melde dich bei deinem WordPress.com-Konto an, das du für die Jetpack-Verbindung verwendet hast. @@ -2156,9 +2156,9 @@ Language: de Keine Schlagwörter entsprechen deiner Suche Du hast keine Schlagwörter Füge deine häufig verwendeten Schlagwörter hier hinzu, sodass du sie beim Markieren deiner Beiträge schnell auswählen kannst - Ein Schlagwort erstellen Keine Medien entsprechen deiner Suche Von WordPress abmelden? + Ein Schlagwort erstellen Es wurden Änderungen an Beiträgen vorgenommen, die nicht auf deine Website hochgeladen wurden. Diese Änderungen gehen verloren, wenn du dich jetzt von deinem Gerät abmeldest. Möchtest du dich trotzdem abmelden? Noch keine Besucher Noch keine E-Mail-Follower @@ -2178,10 +2178,10 @@ Language: de Eine Seite erstellen Medien hochladen Du hast keine Medien + Beitragsbild Bildetgalerie Website-Icon Theme-Bild - Beitragsbild Verwerfen Profilbild Transient @@ -2196,9 +2196,9 @@ Language: de Wird wiederhergestellt auf %1$s %2$s Deine Website wird derzeit wiederhergestellt Deine Website wurde erfolgreich wiederhergestellt + Aktions-Button für Aktivitätsprotokoll Deine Website wurde erfolgreich wiederhergestellt\nWiederhergestellt auf %1$s %2$s Deine Website wird wiederhergestellt\nWird wiederhergestellt auf %1$s %2$s - Aktions-Button für Aktivitätsprotokoll Automatisch verwaltet Speichere diesen Beitrag, um ihn später zu lesen. Er wird nur auf diesem Gerät zur Verfügung stehen – gespeicherte Beiträge werden nicht mit deinen anderen Geräten synchronisiert. Beiträge für später speichern @@ -2251,10 +2251,10 @@ Language: de Beitrag übermittelt Für die Plugin-Funktion ist eine einwandfreie Historie der Website erforderlich. Für die Plugin-Funktion muss dieser Benutzer dem Abonnement für die Hauptdomain zugeordnet sein. - Die Plugin-Funktion erfordert Administratorrechte. Das Plugin kann nicht auf VIP-Websites installiert werden. Das Plugin kann aufgrund von begrenztem Speicherplatz nicht installiert werden. Die Plugin-Funktion erfordert eine bestätigte E-Mail-Adresse. + Die Plugin-Funktion erfordert Administratorrechte. Für die Plugin-Funktion muss die Website öffentlich sein. Für die Plugin-Funktion ist ein Business-Tarif erforderlich. Für die Plugin-Funktion ist eine individuelle Domain erforderlich. @@ -2275,8 +2275,8 @@ Language: de Abonnierte Websites Person, die Benachrichtigungen auf einem Gerät durchliest Personen, die auf Diagramme und Grafiken schauen - %1$s auf %2$s Bist du sicher, dass du diesen Beitrag endgültig löschen möchtest? + %1$s auf %2$s Wichtig Allgemein Dieses Foto verwenden @@ -2292,7 +2292,6 @@ Language: de Schlagwort erstellen nach oben navigieren Benachrichtigungen - Externen Link öffnen weitere anzeigen Foto löschen @@ -2309,13 +2308,14 @@ Language: de Vorschau Audio Video abspielen - Papierkorb erneut versuchen Medienvorschau, Dateiname %s %s entfernen Profilbild von %s Markierungszeichen Anmelden mit Google … + Papierkorb + Externen Link öffnen Verbindung zu Jetpack fehlgeschlagen: %s Du bist bereits mit Jetpack verbunden Visual-Modus @@ -2351,15 +2351,15 @@ Language: de Benachrichtigungen Reader Ich - Meine Webseite Benachrichtigungseinstellungen + Meine Webseite Dein Avatar wurde hochgeladen und ist in Kürze verfügbar. - Es sieht so aus, als hättest du die für diese Funktion erforderlichen Berechtigungen deaktiviert.<br/><br/>Um dies zu ändern, bearbeite deine Berechtigungen und stelle sicher, dass <strong>%s</strong> aktiviert ist. Berechtigungen Vorgestellt Du kannst nicht auf deine Teilen-Einstellungen zugreifen, da dein Sharing Jetpack-Modul deaktiviert ist. Sharing-Modul deaktiviert Version %s + Es sieht so aus, als hättest du die für diese Funktion erforderlichen Berechtigungen deaktiviert.<br/><br/>Um dies zu ändern, bearbeite deine Berechtigungen und stelle sicher, dass <strong>%s</strong> aktiviert ist. Der Pfad für den ausgewählten Ton ist ungültig. Bitte wähle einen anderen. QP %s %1$d Seiten/Beiträge ausstehend @@ -2413,13 +2413,13 @@ Language: de Schließen Es gab Probleme beim Senden dieser E-Mail. Du kannst es jetzt erneut versuchen oder die Seite schließen und es später erneut versuchen. Benutzername - Du kannst dich immer mit einem Link wie dem gerade verwendeten anmelden, du kannst aber auch ein Passwort einrichten, wenn du dies bevorzugst. Passwort (optional) Anzeigename Erneut versuchen Rückgängig machen Es gab Probleme bei der Aktualisierung deines Kontos. Du kannst es erneut versuchen oder deine Änderungen rückgängig machen, um fortzufahren. Es gab Probleme beim Hochladen deines Avatars. + Du kannst dich immer mit einem Link wie dem gerade verwendeten anmelden, du kannst aber auch ein Passwort einrichten, wenn du dies bevorzugst. Benötigt Update Plugins suchen Neu @@ -2447,10 +2447,10 @@ Language: de 3 Sterne 2 Sterne 1 Stern - Nicht vorhanden - %s Downloads %s Bewertungen Bewertungen lesen + Nicht vorhanden + %s Downloads Häufig gestellte Fragen Neues Installation @@ -2462,11 +2462,11 @@ Language: de von %s Foto ändern Plugins konnten nicht geladen werden - Seiten Verwalte deine Website-Schlagwörter Wird gespeichert … - Wird gelöscht Schlagwort „%s“ dauerhaft löschen? + Seiten + Wird gelöscht Ein Schlagwort mit diesem Namen ist bereits vorhanden. Neues Schlagwort hinzufügen Beschreibung @@ -2488,8 +2488,8 @@ Language: de Löschen Externer Link Plugin-Icon - Plugin-Homepage WordPress.org Plugin-Seite + Plugin-Homepage Bist du sicher, dass du %1$s von %2$s entfernen möchtest?\n\nDies deaktiviert das Plugin und löscht alle zugehörigen Dateien und Daten. Plugin entfernen %s wird entfernt… @@ -2498,15 +2498,15 @@ Language: de Fehler beim Entfernen von %s. %s wurde erfolgreich entfernt. Fehler beim Aktualisieren von %1$s: %2$s - Fehler beim Aktualisieren von %s. %s wurde erfolgreich aktualisiert. + Fehler beim Aktualisieren von %s. Version %s ist verfügbar Automatische Updates Aktiv - Inaktiv - Aktiv - Plugins Plugins + Plugins + Aktiv + Inaktiv Link in einem neuen Fenster/Tab öffnen Link zu Ein Fehler ist aufgetreten. @@ -2522,21 +2522,21 @@ Language: de Sende mir stattdessen einen anderen Code per SMS Wir haben eine Textnachricht an die Telefonnummer mit den Endziffern %s gesendet. Gib bitte den Verifizierungscode aus der SMS ein. Größe - 1 Datei verbleibend %1$d von %2$d Dateien verbleibend + 1 Datei verbleibend Ein Beitrag verbleibend Lade hoch … Beitrag verfassen %d Dateien erfolgreich hochgeladen , %d erfolgreich hochgeladen 1 Datei hochgeladen - 1 Datei nicht hochgeladen %d Dateien hochgeladen + 1 Datei nicht hochgeladen %d Dateien nicht hochgeladen Aus Beitrag entfernen Möchtest du dieses Bild aus dem Beitrag entfernen? - Anpassen Datei-Details + Anpassen \nVielleicht probierst du es mit einem anderen Konto? Beim Verbinden mit dem Google-Konto ist ein Problem aufgetreten. Schließen @@ -2553,8 +2553,8 @@ Language: de \"Verbindung mit WordPress.com trennen\" Du kannst eine IP-Adresse oder eine Reihe von IP-Adressen als „Immer zulassen“ markieren und so dafür sorgen, dass diese niemals von Jetpack blockiert werden. IPv4 und IPv6 sind zulässig. Gib für einen Bereich den unteren und oberen Wert ein (getrennt durch einen Bindestrich). Beispiel: 12.12.12.1–12.12.12.100 Zwei-Faktor-Authentifizierung erforderlich - Konten anhand der E-Mail-Adresse abgleichen WordPress.com-Anmeldung zulassen + Konten anhand der E-Mail-Adresse abgleichen WordPress.com-Anmeldung Bösartige Anmeldeversuche blockieren Schutz vor Brute-Force-Angriffen @@ -2569,40 +2569,40 @@ Language: de Zu neuem Beitrag hinzufügen Berechtigungen zum Teilen von Bildern oder Videos erforderlich Ungültige IP-Adresse oder IP-Adressenbereich - Wird gelöscht Dieses Video löschen? + Wird gelöscht Dieses Bild löschen? Dokument-Details Audio-Details Video-Details - Bild-Details Vorschau + Bild-Details Upload-Datum Dauer Videoabmessungen Bildabmessungen + URL Dateityp Dateiname - URL Alternativtext - Eine Website verbinden Blinklicht + Eine Website verbinden Gerät vibrieren lassen Ton auswählen Anzeige und Töne E-Mail von WordPress.com Benachrichtige mich über ausstehende Entwürfe Kommentare auf anderen Websites - Sonstige Alle meine Websites + Sonstige Deine Websites Wenn du Benachrichtigungseinstellungen deaktivierst, werden alle Benachrichtigungen von dieser App, unabhängig vom Typ, deaktiviert. Du kannst detailliert festlegen, welche Art von Benachrichtigung du erhältst, nachdem du die Benachrichtigungseinstellungen aktiviert hast. Um auf diesem Gerät Benachrichtigungen zu erhalten, musst du Benachrichtigungs-Einstellungen aktivieren. Benachrichtigungen aktivieren Benachrichtigungen deaktivieren Deaktiviert - Aktiviert Maximale Videogröße + Aktiviert Maximale Bildgröße Es gab einen Fehler beim Hochladen der Medien in diesem Beitrag: %s. Es gab einen Fehler beim Hochladen dieses Beitrags: %s. @@ -2625,8 +2625,8 @@ Language: de Beitrag geplant Erneut versuchen Beitrag in Warteschlange - „%s“ wird hochgeladen Die Serververbindung ist abgebrochen + „%s“ wird hochgeladen Meine Websites Meine Website E-Mail-Client-App wird nicht erkannt. @@ -2642,8 +2642,8 @@ Language: de Gib die Adresse der WordPress-Website ein, die du verbinden möchtest. Bereits bei WordPress.com angemeldet Weiter - Andere Website verbinden Gib dein WordPress.com-Passwort ein. + Andere Website verbinden Anmelde-E-Mail wird angefordert Dieses Passwort ist anscheinend falsch. Prüfe bitte deine Angaben und versuche es erneut. Verifizierungscode wird per SMS angefordert. @@ -2660,9 +2660,9 @@ Language: de Unerwartete Serverantwort Das Hochladen kann nicht unterbrochen werden, weil es bereits beendet wurde Titel - Wiederherstellen Rückgängig Tut uns leid! Diese Funktion wurde noch nicht implementiert :( + Wiederherstellen Die Medien sind zu klein zum Anzeigen Warnung: Nicht alle abgelegten Elemente werden unterstützt! Im Titel können keine Bilder abgelegt werden @@ -2718,9 +2718,9 @@ Language: de Ändere die Beschriftung der Teilen-Buttons. Dieser Text wird erst angezeigt, wenn du mindestens einen Teilen-Button hinzufügst. Konto verbinden Die %s-Verbindung konnte nicht erstellt werden, da kein Konto ausgewählt wurde. - Verbunden Twitter Likes + Verbunden Zulassen, dass deine Leser und du alle Kommentare mit „Gefällt mir“ kennzeichnen können. Buttons „Mehr“-Buttons bearbeiten @@ -2734,8 +2734,8 @@ Language: de Gefällt mir-Button anzeigen Reblog-Button anzeigen Rebloggen & Gefällt mir - Offizielle Buttons Nur Text + Offizielle Buttons Nur Icon Icon & Text Wähle das Konto aus, das du autorisieren möchtest. Bitte beachte, dass deine Beiträge automatisch mit dem ausgewählten Konto geteilt werden. @@ -2752,8 +2752,8 @@ Language: de Benachrichtigungen. Verwalte deine Benachrichtigungen. Reader. Inhalten anderer Websites folgen. Meine Website. Zeige deine Website an und verwalte sie, einschließlich Statistiken. - Teilen Nicht jetzt + Teilen Fehler beim Hochladen. Versuche es mit der Funktion Optimize Images unter Site->Settings Mediendatei auf diesem Gerät speichern Medien konnten nicht gespeichert werden @@ -2764,8 +2764,8 @@ Language: de Tippe und halte, um mehrere Kommentare auszuwählen. Wähle ein Video auf deinem Gerät aus. Wähle ein Foto auf deinem Gerät aus. - WordPress Medien Als Galerie hinzufügen. + WordPress Medien Einzeln hinzufügen mehrere Fotos hinzufügen %d Spalten @@ -2799,11 +2799,11 @@ Language: de Mittel Niedrig Hochgeladen - Hochladen fehlgeschlagen Gelöscht - Wird gelöscht Lade hoch In Warteschlange + Hochladen fehlgeschlagen + Wird gelöscht Bildqualität Aufgrund eines unbekannten Fehlers wurden alle Medien-Uploads abgebrochen. Bitte versuche erneut, die Inhalte hochzuladen Unbekanntes Beitragsformat @@ -2849,61 +2849,61 @@ Language: de Gefällt mir … Wird verarbeitet … Aktion erledigt! - Kommentar gefällt mir Abmelden Bei WordPress.com anmelden + Kommentar gefällt mir Mehr auf WordPress.com Mehr von %s Geräte-Einstellungen öffnen - %s: Ungültige E-Mail %s: Benutzer blockiert Einladungen + %s: Ungültige E-Mail %s: Folge ich bereits - %s: Bereits ein Mitglied %s: Benutzer nicht gefunden + %s: Bereits ein Mitglied Kommentar freigegeben! Like Jetzt - Besucher Follower + Besucher Keine Verbindung, dein Profil konnte nicht gespeichert werden - Rechts Links + Rechts Keine Ausgewählt %1$d Website-Benutzer konnten nicht abgerufen werden - E-Mail-Follower Follower + E-Mail-Follower Benutzer werden abgerufen … - Besucher E-Mail-Follower + Besucher Follower Team Lade bis zu 10 E-Mail-Adressen und/oder WordPress.com Benutzernamen ein. Diejenigen, welche einen Benutzernamen benötigen, werden eine Anleitung gesendet bekommen, wie sie einen erstellen. Falls du diesen Besucher entfernst, kann er oder sie die Website nicht mehr ansehen.\n\nMöchtest du diesen Besucher noch immer entfernen? Nach dem Entfernen bekommt der Follower keine Mitteilungen über dieser Website mehr, bis er wieder folgt.\n\nMöchtest du diesen Follower noch immer entfernen? Seit %1$s - Konnte Besucher nicht entfernen Konnte Follower nicht entfernen + Konnte Besucher nicht entfernen Konnte E-Mail-Follower der Website nicht abrufen Konnte Follower der Website nicht abrufen Einige Medien konnten nicht hochgeladen werden. Du kannst daher derzeit nicht in den HTML-Modus umschalten. Möchtest du alle fehlgeschlagenen Uploads entfernen und fortfahren? - Vorschaubild Visueller Editor + Vorschaubild Breite - Link zu + Änderungen gespeichert Alternativtext Bildunterschrift - Änderungen gespeichert + Link zu Ungespeicherte Änderungen verwerfen? Hochladen stoppen? Beim Einfügen von Medien ist ein Fehler aufgetreten Derzeit lädst du noch Medien hoch. Bitte warte bis der Vorgang abgeschlossen ist. Du kannst keine Medien im HTML-Modus einfügen. Bitte wechsle zurück in den Visuellen Editor und versuche es erneut. Galerie wird hochgeladen… - Tippe, um es erneut zu versuchen! + Einladung gesendet, aber es ist mindestens ein Fehler aufgetreten. Einladung erfolgreich gesendet %1$s: %2$s - Einladung gesendet, aber es ist mindestens ein Fehler aufgetreten. + Tippe, um es erneut zu versuchen! Ein Fehler ist während dem Senden der Einladung aufgetreten! Senden fehlgeschlagen: Es wurden ungültige Benutzernamen oder E-Mail-Adressen angegeben Senden fehlgeschlagen: Benutzername oder E-Mail-Adresse sind ungültig @@ -2920,12 +2920,12 @@ Language: de Ähnliche Beiträge Im Vorschaubildschirm sind Links deaktiviert. Senden - \@%1$s erfolgreich entfernt Falls du %1$s entfernst, kann dieser Benutzer nicht länger auf die Website zugreifen, aber alle von %1$s erstellten Beiträge verbleiben auf der Website.\n\nMöchtest du diesen Benutzter noch immer entfernen? + \@%1$s erfolgreich entfernt Entferne %1$s Rolle - Personen Die Websites dieser Liste haben keine neuen Beiträge + Personen Benutzer konnte nicht entfernt werden Benutzerrolle konnte nicht aktualisiert werden Website-Besucher konnten nicht abgerufen werden @@ -2938,14 +2938,14 @@ Language: de Anmeldung läuft Wird mit deinem Kommentar veröffentlicht. Foto aufnehmen oder auswählen - Tarife Tarif + Tarife Deine Beiträge, Seiten und Einstellungen werden dir per E-Mail an %s gesendet. Exportiere deine Inhalte Exort E-Mail gesendet! Inhalt wird exportiert&hellip; - Überprüfe Einkäufe Käufe anzeigen + Überprüfe Einkäufe Du hast aktive Premium Upgrades auf deiner Website. Bitte storniere diese Upgrades, bevor du deine Website löschst. Premium Upgrades Es ist ein Fehler aufgetreten. Einkäufe konnten nicht abgefragt werden. @@ -2957,8 +2957,8 @@ Language: de Fehler beim Löschen der Website Inhalte exportieren Bitte gib %1$s zur Bestätigung unten in das Feld ein. Dann ist deine Website für immer entfernt. - Löschen der Website bestätigen Support kontaktieren + Löschen der Website bestätigen Wenn du eine Website haben möchtest, aber ohne deine aktuellen Beiträge und Seiten, kann unser Support-Team deine Beiträge, Seiten, Medien und Kommentare für dich löschen.\n\nSo bleiben deine Website und URL aktiv, aber du kannst von Neuem mit der Erstellung von Inhalten beginnen. Kontaktiere uns einfach, damit wir deine aktuellen Inhalte entfernen. Lass uns helfen Nochmal mit deiner Website beginnen @@ -2971,34 +2971,34 @@ Language: de Keine genehmigten Kommentare Überspringen Konnte nicht verbinden. Die benötigte XML-RPC Methoden sind nicht auf dem Server vorhanden. - Zentriert - Video Status - Standard - Zitat - Link - Bild - Galerie + Video + Zentriert Chat - Audio - Kurzmitteilung + Galerie + Bild + Link + Zitat + Standard Informationen zu WordPress.com-Kursen und -Veranstaltungen (online und vor Ort) + Kurzmitteilung + Audio Gelegenheiten, an Marktforschung und Befragungen von WordPress.com teilzunehmen Tipps für die optimale Nutzung von WordPress.com Community - Marktforschung - Vorschläge Antworten auf meine Kommentare - Benutzernamen-Erwähnungen + Vorschläge + Marktforschung Website-Auszeichnungen - Website-Follows + Benutzernamen-Erwähnungen Likes für meine Beiträge + Website-Follows Likes für meine Kommentare Kommentare auf meiner Website %d Einträge 1 Eintrag - Alle Benutzer Kommentare bekannter Benutzer + Alle Benutzer Keine Kommentare %d Kommentare pro Seite 1 Kommentar pro Seite @@ -3008,11 +3008,11 @@ Language: de Alle Kommentare automatisch genehmigen Automatisch genehmigen, wenn bereits andere Kommentare des Benutzers genehmigt wurden Alle Kommentare müssen manuell genehmigt werden. - %d Tage 1 Tag - Web-Adresse - Primäre Website + %d Tage Klicke auf den Bestätigungslink in der E-Mail, die an %1$s gesendet wurde, um deine neue Adresse zu bestätigen. + Primäre Website + Web-Adresse Medien werden hochgeladen … Bitte warte, bis der Vorgang abgeschlossen ist. Die Kommentare konnten nicht aktualisiert werden. Es werden ältere Kommentare angezeigt. Beitragsbild festlegen @@ -3021,13 +3021,13 @@ Language: de Möchtest du diese Kommentare dauerhaft löschen? Möchtest du diesen Kommentar dauerhaft löschen? Löschen - Wiederherstellen Kommentar gelöscht + Wiederherstellen Keine Spam-Kommentare - Alle Seite konnte nicht geladen werden. - Aus + Alle Sprache der Bedienoberfläche + Aus Über die App Deine Kontoeinstellungen konnten nicht gespeichert werden. Deine Kontoeinstellungen konnten nicht abgerufen werden. @@ -3035,9 +3035,9 @@ Language: de Sprachcode nicht erkannt Zulassen, dass Kommentare in Threads verschachtelt werden. Verschachteln bis zu - Deaktiviert - Suche Entfernen + Suche + Deaktiviert Originalgröße Deine Website ist nur für dich und freigegebene Nutzer sichtbar. Deine Website ist für alle sichtbar. Suchmaschinen werden aufgefordert, sie nicht zu indexieren. @@ -3046,9 +3046,9 @@ Language: de Über mich Wenn du keinen Anzeigenamen festlegst, wird standardmäßig dein Benutzername verwendet. Öffentlich angezeigter Name - Nachname - Vorname Mein Profil + Vorname + Nachname Vorschaubild für ähnlichen Beitrag Website-Info konnte nicht gespeichert werden Website-Info konnte nicht abgerufen werden @@ -3103,8 +3103,8 @@ Language: de %d Ebenen Privat Versteckt - Öffentlich Website löschen + Öffentlich Zur Freischaltung überprüfen Links in Kommentaren Automatisch genehmigen @@ -3119,22 +3119,22 @@ Language: de Standardformat Standardkategorie Adresse - Untertitel Website-Titel + Untertitel Standardeinstellungen für neue Beiträge - Schreiben Konto + Schreiben Allgemein Neuester zuerst - Ältester zuerst - Schließen nach Kommentare - Ähnliche Beiträge - Datenschutz Diskussionen + Datenschutz + Ähnliche Beiträge + Schließen nach + Ältester zuerst Du hast keine Berechtigung Medien auf diese Website hochzuladen - Unbekannt Nie + Unbekannt Dieser Beitrag ist nicht mehr vorhanden Du hast nicht die erforderlichen Rechte diesen Beitrag anzusehen Konnte den Beitrag nicht empfangen @@ -3146,18 +3146,18 @@ Language: de Etwas ist schief gelaufen. Konnte Theme nicht aktivieren von %1$s Danke, dass du %1$s gewählt hast - WEBSITE VERWALTEN - FERTIG - Support - Details Anzeigen + Details + Support + FERTIG Ausprobieren & Anpassen + WEBSITE VERWALTEN Aktivieren - Aktiv - Support - Details - Anpassen Aktuelles Theme + Anpassen + Details + Support + Aktiv Seite aktualisiert Beitrag aktualisiert Seite veröffentlicht @@ -3193,19 +3193,19 @@ Language: de Benachrichtigungstypen Konnte Benachrichtigungs-Einstellungen nicht laden Kommentar-Likes - App-Benachrichtigungen E-Mail + App-Benachrichtigungen Registerkarte „Benachrichtigungen“ Wichtige E-Mails bezüglich deines Kontos werden immer versandt, aber du kannst auch zusätzliche Benachrichtigungen erhalten. Übersicht des letzten Beitrags Keine Verbindung - Beitrag in den Papierkorb verschoben - In den Papierkorb - Statistiken Vorschau Anzeigen - Veröffentlichen Bearbeiten + Veröffentlichen + Beitrag in den Papierkorb verschoben + Statistiken + In den Papierkorb Du bist nicht berechtigt, auf diese Website zuzugreifen Diese Website konnte nicht gefunden werden Rückgängig @@ -3216,257 +3216,257 @@ Language: de Beiträge, Aufrufe und Besucher für den gesamten Zeitraum Einsichten Bei WordPress.com abmelden - Bei WordPress.com anmelden Anmelden/Abmelden + Bei WordPress.com anmelden Konto-Einstellungen „%s“ wurde nicht ausgeblendet, denn es ist die aktuelle Website WordPress.com-Website erstellen - Selbst gehostete Website hinzufügen - Website hinzufügen Websites anzeigen/ausblenden - Website auswählen - Website ansehen + Website hinzufügen + Selbst gehostete Website hinzufügen Admin aufrufen + Website ansehen + Website auswählen Website wechseln + Erscheinungsbild + Veröffentlichen Website-Einstellungen Beiträge - Veröffentlichen - Erscheinungsbild Einrichtung Berühren zum Anzeigen Alle abwählen - Alle auswählen - Ausblenden Anzeigen - Melde dich erneut an, um fortzufahren. - Ungültiger Überprüfungscode - Überprüfungscode + Ausblenden + Alle auswählen Sprache - Beiträge können nicht abgerufen werden - Benachrichtigung konnte nicht geöffnet werden - Unbekannte Suchbegriffe - Suchbegriffe + Überprüfungscode + Ungültiger Überprüfungscode + Melde dich erneut an, um fortzufahren. Autoren + Suchbegriffe + Unbekannte Suchbegriffe Seiten werden abgerufen… - Beiträge werden abgerufen… Medien werden abgerufen… + Beiträge werden abgerufen… + Beiträge können nicht abgerufen werden + Benachrichtigung konnte nicht geöffnet werden Anwendungsprotokolle wurden in die Zwischenablage kopiert - Diese Website ist leer Neue Beiträge Beim Kopieren von Text in die Zwischenablage ist ein Fehler aufgetreten Beitrag wird hochgeladen - %1$d Jahre - Ein Jahr + Diese Website ist leer + Themes werden abgerufen… %1$d Monate + Ein Jahr + %1$d Jahre Ein Monat - %1$d Tage - Ein Tag - %1$d Stunden - Vor einer Stunde %1$d Minuten + Vor einer Stunde + %1$d Stunden + Ein Tag + %1$d Tage Vor einer Minute Vor Sekunden - Follower - Videos Beiträge & Seiten + Videos + Follower Länder Gefällt mir - Besucher - Aufrufe Jahre - Themes werden abgerufen… + Aufrufe + Besucher Details %d ausgewählt Die FAQ durchsuchen Keine Kommentare bisher - Keine Beiträge mit diesem Thema - Gefällt mir Zeige Original-Beitrag + Gefällt mir Kommentare sind geschlossen %1$d von %2$d Leerer Beitrag kann nicht veröffentlicht werden Du hast keine Berechtigung Beiträge anzusehen oder zu bearbeiten Du hast keine Berechtigung Seiten anzusehen oder zu bearbeiten - Mehr Älter als ein Monat - Älter als eine Woche + Mehr Älter als zwei Tage - Hilfe & Support + Älter als eine Woche Gefällt Kommentar Kommentar im Papierkorb - Antwort zu %s Keine Beiträge bisher. Warum nicht jetzt einen erstellen? + Antwort zu %s Abmelden … + Keine Beiträge mit diesem Thema + Hilfe & Support Konnte diese Aktion nicht ausführen + Diese Website blockieren Kann diese Website nicht blockieren Beiträge von dieser Website werden nicht länger angezeigt - Diese Website blockieren Zeitplan Aktualisieren - Keine empfohlenen Websites - Kann das Folgen dieser Website nicht beenden - Kann dieser Website nicht folgen + Abonnierte Websites Du folgst dieser Website bereits + Kann dieser Website nicht folgen + Kann das Folgen dieser Website nicht beenden + Keine empfohlenen Websites Diese Website kann nicht angezeigt werden Website wird verfolgt - Gib eine URL oder ein Thema ein, der/dem du folgen möchtest - Abonnierte Websites - Abonnierte Themen Reader-Website - Wenn du dich üblicherweise ohne Probleme mit dieser Website verbinden kannst, könnte dieser Fehler bedeute, dass sich jemand als diese Website ausgibt und du daher nicht weitermachen solltest. Möchtest du dem Zertifikat trotzdem vertrauen? - Ungültiges SSL Zertifikat + Abonnierte Themen + Gib eine URL oder ein Thema ein, der/dem du folgen möchtest Hilfe - Der Benutzername oder das Passwort ist falsch - Gib eine gültige E-Mail-Adresse ein - Deine E-Mail-Adresse ist ungültig - Fehler beim Herunterladen des Bildes + Ungültiges SSL Zertifikat + Wenn du dich üblicherweise ohne Probleme mit dieser Website verbinden kannst, könnte dieser Fehler bedeute, dass sich jemand als diese Website ausgibt und du daher nicht weitermachen solltest. Möchtest du dem Zertifikat trotzdem vertrauen? + Es ist kein Netzwerk verfügbar + Das Medien-Objekt konnte nicht abgerufen werden + Kein Spam + Kategorie erfolgreich hinzugefügt + Keine Benachrichtigungen + Es ist ein Fehler aufgetreten Kommentar konnte nicht geladen werden + Fehler beim Herunterladen des Bildes + Deine E-Mail-Adresse ist ungültig + Gib eine gültige E-Mail-Adresse ein + Der Benutzername oder das Passwort ist falsch Beim Bearbeiten des Kommentars ist ein Fehler aufgetreten - Bei der Moderation trat ein Fehler auf - Es ist ein Fehler aufgetreten - Kommentare konnten nicht aktualisiert werden + Hinzufügen der Kategorie fehlgeschlagen Seiten konnten nicht aktualisiert werden - Beiträge konnten nicht aktualisiert werden - Beim Löschen des Beitrags ist ein Fehler aufgetreten - Keine Benachrichtigungen + Bei der Moderation trat ein Fehler auf + Abrufen der Themes fehlgeschlagen Eine angeschlossene SD-Karte wird für den Medienupload benötigt + Kommentare konnten nicht aktualisiert werden Das Feld Kategorie-Name ist erforderlich - Kategorie erfolgreich hinzugefügt - Hinzufügen der Kategorie fehlgeschlagen - Kein Spam - Abrufen der Themes fehlgeschlagen Beim Aufrufen des Blogs ist ein Fehler aufgetreten - Das Medien-Objekt konnte nicht abgerufen werden - Es ist kein Netzwerk verfügbar - Dieses Thema konnte nicht entfernt werden - Dieses Thema konnte nicht hinzugefügt werden - Anwendungslog - Bei der Erstellung der App-Datenbank ist ein Fehler aufgetreten. Versuche die App erneut zu installieren. - Dieser Blog ist versteckt und konnte nicht geladen werden. Aktiviere ihn wieder in den Einstellungen und versuche es erneut. - Die Medien konnten zu diesem Zeitpunkt nicht aktualisiert werden - WordPress-Blog + Beiträge konnten nicht aktualisiert werden + Beim Löschen des Beitrags ist ein Fehler aufgetreten + Fehler beim Verbinden + Bearbeiten abbrechen + Kategorien auswählen + Mehr erfahren + Link erstellen + Lokaler Entwurf + Horizontale Ausrichtung + Spam + Papierkorb + Spam + Kommentar bearbeiten + Ablehnen + Im Browser anschauen + Neue Kategorie hinzufügen Bild-Einstellungen - Lokale Änderungen - Neue Mediendatei + Kommentar wird benötigt + Papierkorb + Ausstehend + Kommentar wurde nicht verändert Neuer Beitrag - Keine Benachrichtigung bisher. + Anwendungslog Autorisierung erforderlich - Überprüfe, ob die eingegebene Website-URL gültig ist. - Konnte keine temporäre Datei für den Medienupload erstellen. Stelle sicher, dass genügend Speicherplatz auf deinem Gerät verfügbar ist. - Kategorie-Name - Neue Kategorie hinzufügen - Im Browser anschauen - Website entfernen - Kommentar wurde nicht verändert - Kommentar wird benötigt + Neue Mediendatei + Lokale Änderungen + Gelöscht Bearbeiten des Kommentars abbrechen? - Änderungen speichern - Papierkorb In Papierkorb verschieben? - Papierkorb - Spam - Ablehnen + Linktext (optional) + Änderungen speichern + WordPress-Blog + Bei der Erstellung der App-Datenbank ist ein Fehler aufgetreten. Versuche die App erneut zu installieren. + Kategorie-Name Genehmigen - Kommentar bearbeiten - Gelöscht - Spam - Ausstehend - Freigegeben - Seite löschen? - Beitrag löschen? + Einige Mediendateien konnten nicht gelöscht werden. Versuche es später erneut. + Vorschaubild-Raster + Konnte keine temporäre Datei für den Medienupload erstellen. Stelle sicher, dass genügend Speicherplatz auf deinem Gerät verfügbar ist. + Website entfernen + Seiten-Einstellungen Beitrags-Einstellungen + Keine Benachrichtigung bisher. + Überprüfe, ob die eingegebene Website-URL gültig ist. Mediendatei für den Upload konnte nicht gefunden werden. Wurde sie gelöscht oder verschoben? - Horizontale Ausrichtung - Lokaler Entwurf - Seiten-Einstellungen - Link erstellen - Linktext (optional) - Einige Mediendateien konnten nicht gelöscht werden. Versuche es später erneut. + Beim Zugriff auf dieses Plugin ist ein Fehler aufgetreten + Die Medien konnten zu diesem Zeitpunkt nicht aktualisiert werden + Freigegeben Du hast keine Berechtigung die Mediathek zu sehen - Vorschaubild-Raster - Mehr erfahren + Beitrag löschen? + Seite löschen? Beim Abrufen des Beitrags trat ein Fehler auf. Lade deine Beiträge neu und versuche es erneut. - Beim Zugriff auf dieses Plugin ist ein Fehler aufgetreten - Bearbeiten abbrechen - Fehler beim Verbinden - Kategorien auswählen + Dieser Blog ist versteckt und konnte nicht geladen werden. Aktiviere ihn wieder in den Einstellungen und versuche es erneut. + Dieses Thema konnte nicht hinzugefügt werden + Dieses Thema konnte nicht entfernt werden Link teilen Beiträge werden abgerufen… - Dir und %,d anderen gefällt dies - %d Leuten gefällt dies - Du kannst nicht auf WordPress teilen ohne einen sichtbaren Blog Kommentar als Spam markiert Kommentar nicht mehr genehmigt - Beitrag konnte nicht geladen werden - Dir und einem anderen gefällt dies - Video auswählen + %d Leuten gefällt dies + Du kannst nicht auf WordPress teilen ohne einen sichtbaren Blog + Dir und %,d anderen gefällt dies Foto auswählen - Registrieren + Video auswählen + Dir und einem anderen gefällt dies + Beitrag konnte nicht geladen werden + %s hinzugefügt + %s entfernt + Einer Person gefällt das + Dir gefällt das Konnte %s nicht öffnen Kann das Bild nicht anzeigen Teilen nicht möglich - Das ist kein gültiges Thema - Du folgst diesem Thema bereits - Konnte deinen Kommentar nicht veröffentlichen - Dir gefällt das - Einer Person gefällt das - %s entfernt - %s hinzugefügt - Antwort auf Kommentar… - Folge ich - Folgen Teilen - Rebloggen + Diese Liste ist leer (Ohne Titel) + Folgen + Folge ich + Antwort auf Kommentar… Bisher keine Kommentare - Diese Liste ist leer - Monate - Wochen - Tage - Gestern - Heute - Referrer - Tags & Kategorien - Klicks - Statistik - Teilen + Rebloggen + Konnte deinen Kommentar nicht veröffentlichen + Das ist kein gültiges Thema + Du folgst diesem Thema bereits + Registrieren + Themes + Quadrate + Gekachelt + Kreise Aktivieren - Aktualisierung fehlgeschlagen - Beschreibung - Beschriftung + Teilen + Statistik + Heute + Gestern + Tage + Wochen + Monate Titel + Beschriftung + Beschreibung + Klicks + Tags & Kategorien + Referrer Slideshow - Kreise - Gekachelt - Quadrate - Themes - Verwerfen + Aktualisierung fehlgeschlagen Verwalten - und %d weitere. + Verwerfen + Anmelden + Antwort veröffentlicht %d neue Benachrichtigungen + und %d weitere. Folgt - Antwort veröffentlicht - Anmelden Wird geladen … - HTTP-Passwort HTTP-Benutzername + HTTP-Passwort Beim Hochladen von Medien ist ein Fehler aufgetreten Falscher Benutzername oder falsches Passwort. - Anmelden - Benutzername Passwort + Benutzername + Anmelden Reader - Bild im Beitragsinhalt verwenden - Als Beitragsbild nutzen + Kein Netzwerk verfügbar + Seiten Breite + Anonym Bildunterschrift (optional) - Seiten Beiträge - Anonym - Kein Netzwerk verfügbar - erledigt + Als Beitragsbild nutzen + Bild im Beitragsinhalt verwenden OK + erledigt URL Lädt hoch… Ausrichtung @@ -3479,27 +3479,27 @@ Language: de Name des Tastaturkürzel darf nicht leer sein Privat Titel - Schlagwörter (durch Kommas getrennt) Kategorien + Schlagwörter (durch Kommas getrennt) SD-Karte benötigt Medien Kategorie erfolgreich aktualisiert - Genehmigen Löschen - Aktualisieren der Kategorie fehlgeschlagen + Genehmigen Nichts - Jetzt veröffentlichen + Aktualisieren der Kategorie fehlgeschlagen Antworten - zu Vorschau - Fehler beim Aktualisieren der Kategorien - Fehler - Nein + zu + Abbrechen + Speichern + Hinzufügen Ja + Nein + Fehler + Fehler beim Aktualisieren der Kategorien Benachrichtigungs-Einstellungen - Hinzufügen - Speichern - Abbrechen + Jetzt veröffentlichen Einmal Zweimal diff --git a/WordPress/src/main/res/values-en-rCA/strings.xml b/WordPress/src/main/res/values-en-rCA/strings.xml index d73073b418e7..2c0bc69a8220 100644 --- a/WordPress/src/main/res/values-en-rCA/strings.xml +++ b/WordPress/src/main/res/values-en-rCA/strings.xml @@ -8,127 +8,127 @@ Language: en_CA Your site has the Jetpack plugin Get notifications for new comments, likes, views, and more. - Watch your traffic grow with helpful insights and comprehensive stats. Find and follow your favourite sites and communities, and share you content. + Watch your traffic grow with helpful insights and comprehensive stats. Stats & Insights - Blogging Prompts hidden Give WordPress a boost with Jetpack - Visit <b>Site Settings</b> to turn back on Notification will include a word or short phrase for inspiration - Blogging - Show prompts - Community forums + Visit <b>Site Settings</b> to turn back on + Blogging Prompts hidden Turn off prompts - Blogging reminders Get help from our group of volunteers. + Community forums + Blogging reminders + Show prompts + Blogging Please install Google Play Store to get the Jetpack app - Stats, Reader, Notifications and other Jetpack powered features have been removed from the WordPress app. - Jetpack features have moved. Do this later Switch to Jetpack + Stats, Reader, Notifications and other Jetpack powered features have been removed from the WordPress app. + Jetpack features have moved. %1$s are moving in %2$s - %1$s are moving soon %1$s is moving in %2$s + %1$s are moving soon %1$s is moving soon + Get the Jetpack app View all responses %1$s lower than the previous 7-days %1$s higher than the previous 7-days - Your views in the last 7-days are %1$s lower than the previous 7-days. - Your views in the last 7-days are %1$s higher than the previous 7-days. Your visitors in the last 7-days are %1$s lower than the previous 7-days. Your visitors in the last 7-days are %1$s higher than the previous 7-days. - Last 7-days + Your views in the last 7-days are %1$s lower than the previous 7-days. + Your views in the last 7-days are %1$s higher than the previous 7-days. Previous 7-days - 1 week + Last 7-days %d weeks - Get the Jetpack app + 1 week From <b>DayOne</b> Hide this Remind me later + Switch to the Jetpack app Learn more at jetpack.com Switching is free and only takes a minute. - Stats, Reader, Notifications and other Jetpack powered features will be removed from the WordPress app on %s. Stats, Reader, Notifications and other Jetpack powered features will be removed from the WordPress app soon. - Switch to the Jetpack app - There was an error loading prompts. - Oops - Check your network connection and try again. - Unable to load this content right now - No prompts yet - 1 answer - %d answers - 0 answers + Stats, Reader, Notifications and other Jetpack powered features will be removed from the WordPress app on %s. Jetpack features are moving soon. Notifications are moving to Jetpack Reader is moving to the Jetpack app Your stats are moving to the Jetpack app Switch to the new Jetpack app + Check your network connection and try again. + Unable to load this content right now + There was an error loading prompts. + Oops + No prompts yet + %d answers + 1 answer + 0 answers ✓ Answered Prompts close Alternatively, you can detach and edit this block separately by tapping “Convert to regular block”. - Deleting category failed - Category deleted successfully Permanently delete \'%s\' Category? + Category deleted successfully + Deleting category failed Deleting category - Update category Updating category + Update category + Posts from this user will no longer be shown Block user Report this user - Posts from this user will no longer be shown - urilinks - weblinks - Continue without Jetpack Open links in WordPress It looks like you have the Jetpack app installed.\n\nWould you like to open links in the Jetpack app in the future?\n\nYou can always change this in App Settings > Open links in Jetpack Open links in Jetpack? - Switch to the Jetpack app to keep receiving realtime notifications on your device. - Jetpack provides stats, notifications and more to help you build and grow the WordPress site of your dreams. + Continue without Jetpack Jetpack provides stats, notifications and more to help you build and grow the WordPress site of your dreams.\n\nThe WordPress app no longer supports creating a new site. + Jetpack provides stats, notifications and more to help you build and grow the WordPress site of your dreams. Create a new WordPress site with the Jetpack app + weblinks + urilinks + Switch to the Jetpack app to keep receiving realtime notifications on your device. Switch to the Jetpack app to find, follow, and like all your favorite sites and posts with Reader. Switch to the Jetpack app to watch your site’s traffic grow with stats and insights. - Please <b>delete the WordPress app</b> to avoid data conflicts. - Got it - Need help? - Open links in Jetpack - Unable to disable open links in Jetpack - Unable to enable open links in Jetpack Get your notifications with the Jetpack app Follow any site with the Jetpack app Get your stats using the new Jetpack app + Unable to disable open links in Jetpack + Unable to enable open links in Jetpack + Open links in Jetpack + Need help? + Got it + Please <b>delete the WordPress app</b> to avoid data conflicts. It looks like you still have the WordPress app installed. We recommend you delete the WordPress app to avoid data conflicts. You no longer need the WordPress app - Please contact support or try again later. - We’re sorry but something didn’t go as planned. Your data is safe, but we’re unable to transfer it at this time. We are unable to transfer your data and settings without a network connection. Please check to make sure your network connection is working and try again. Unable to connect to the internet. - Please <b>delete the WordPress app</b> to avoid data conflicts. - Finish + Please contact support or try again later. + We’re sorry but something didn’t go as planned. Your data is safe, but we’re unable to transfer it at this time. Uh oh, something went wrong.. - Remove WordPress App icon Try again + Finish + Remove WordPress App icon + Please <b>delete the WordPress app</b> to avoid data conflicts. We’ve transferred all your data and settings. Everything is right where you left it. Thanks for switching to Jetpack! We\'ll turn off notifications from the WordPress app. You’ll get all the same notifications but now they’ll come from the Jetpack app. Notifications now come from Jetpack Please delete the WordPress app + WordPress help center + Support Allows the app to disable WordPress notifications. disable WordPress notifications - Support - WordPress help center - Your profile photo - Continue Need help? + Continue We found your site. Continue to transfer all your data and sign in to Jetpack automatically. We found your sites. Continue to transfer all your data and sign in to Jetpack automatically. + Your profile photo It looks like you’re switching from the WordPress app. Welcome to Jetpack! icon - Page Attributes Parent Page + Page Attributes Contribute News 1 answer @@ -139,44 +139,40 @@ Language: en_CA Enjoying %s? Share post to %s Jetpack Social Connections - Jetpack Social Connections Please log in to the Jetpack app to add a widget. + Jetpack Social Connections We just sent a magic link to Check your email on this device! Use password to sign in - Notifications are powered by Jetpack Stay informed with realtime updates for new comments, site traffic, security reports and more. - Reader is powered by Jetpack - Find, follow, and like all your favorite sites and posts with Reader, now available in the new Jetpack app. - Stats are powered by Jetpack + Notifications are powered by Jetpack Watch your traffic grow and learn about your audience with redesigned Stats and Insights, now available in the new Jetpack app. - WordPress is better with Jetpack + Stats are powered by Jetpack + Find, follow, and like all your favorite sites and posts with Reader, now available in the new Jetpack app. + Reader is powered by Jetpack The new Jetpack app has Stats, Reader, Notifications, and more that make your WordPress better. - Gradient - Invalid URL. - Jetpack powered - Upgrade your plan to upload audio + WordPress is better with Jetpack Upgrade your plan to use video covers + Upgrade your plan to upload audio + Jetpack powered + Invalid URL. + Gradient Continue to Notifications - Continue to Reader Continue to Stats + Continue to Reader Try the new Jetpack app Problem displaying block. \nTap to attempt block recovery. - ⭐️ Your latest post %1$s has received %2$s like. - Last week you had %1$s views, %2$s likes, and %3$s comments. Last week you had %1$s views and %2$s comments Last week you had %1$s views and %2$s likes Last week you had %1$s views. + Last week you had %1$s views, %2$s likes, and %3$s comments. + ⭐️ Your latest post %1$s has received %2$s like. Jetpack powered Image indicating scan log-in code in process Image indicating an error Are you sure you want to continue? Exit Scan Log-in Code Flow Could not log you in using this log-in code. Please tap the Scan Again button to rescan the code. - You\'re logged in! - Yes, log me in - Only scan QR codes taken directly from your web browser. Never scan a code sent to you by anyone else. - Are you trying to log in to your web browser near %1$s? Authentication Failed This log-in code has expired. Please tap the Scan Again button to rescan the code. Expired log-in code @@ -187,20 +183,20 @@ Language: en_CA Scan Again Dismiss Tap dismiss and head back to your web browser to continue. + You\'re logged in! + Yes, log me in + Only scan QR codes taken directly from your web browser. Never scan a code sent to you by anyone else. + Are you trying to log in to your web browser near %1$s? Are you trying to log in to %1$s near %2$s? 💡Commenting on other blogs is a great way to build attention and followers for your new site. 💡Tap \'VIEW MORE\' to see your top commenters. - ✍️ Schedule your drafts to publish at the best time to reach your audience. Check back when you\'ve published your first post! Check out our top tips to increase your views and traffic %1$s + ✍️ Schedule your drafts to publish at the best time to reach your audience. 💡Posting consistently is a great way to build your audience. Add a reminder to keep you on track. 💡Level up your blogging faster with our expert-led <i>Intro to Blogging</i> course. Blogging Prompts are loading. Please wait a moment and try again. Can\'t decide? You can change the theme at any time. - Search - WordPress - Views - Schedule Blogging Picked for you Best for %s @@ -210,29 +206,36 @@ Language: en_CA Learn more Totals Others + Search + WordPress + Views + Schedule Schedule your post Set reminders Set your blogging reminders Check the course Grow your audience - All tasks completed - Task complete - Scan Log-in Code You can also rearrange blocks by tapping a block and then tapping the up and down arrows that appear on the bottom left side of the block to move it up or down. Image file not found. Drag & drop makes rearranging blocks a breeze. Press and hold on a block, then drag it to its new location and release. Drag & drop Arrow buttons %1$s. Currently selected: %2$s + All tasks completed + Task complete + Scan Log-in Code ⭐️ Your latest post %1$s has received %2$s likes. Not enough activity. Check back later when your site\'s had more visitors! - %1$s (%2$s%%) %1$s, %2$s%% of total followers + %1$s (%2$s%%) Copy link Congrats! You know your way around<br/> Get to know the app Bring media straight from your device or camera to your site Upload photos or videos + Get real-time updates from your pocket + Select %1$s Media %2$s to see your current library. + Get real-time updates from your pocket. Check your notifications Select the %1$s Notifications tab %2$s to get updates on the go. Select %1$s plus %2$s to upload media. You can add it to your posts/pages from any device. @@ -240,9 +243,12 @@ Language: en_CA Use <b> Discover </b> to find sites and tags. Try selecting %1$s Settings %2$s to add topics you like. Video Thumbnail Top Commentators - Get real-time updates from your pocket - Select %1$s Media %2$s to see your current library. - Get real-time updates from your pocket. + Published %1$d years ago + Published a year ago + Published %1$d months ago + Published a month ago + Published %1$d days ago + Published a day ago Published %1$d hours ago Published an hour ago Published %1$d minutes ago @@ -251,12 +257,6 @@ Language: en_CA Total Followers Total Comments Total Likes - Published %1$d years ago - Published a year ago - Published %1$d months ago - Published a month ago - Published %1$d days ago - Published a day ago Dismiss Answer Daily Prompt @@ -278,11 +278,11 @@ Language: en_CA Initial Screen Learn more Become a better writer by building a writing habit. Tap to learn more. + New in the WordPress mobile app: Prompts + A good name is short and memorable.\nYou can change it later. Give your %s website a name Site name Interested in building your audience? Check out our <a href=\"%1$s\">top tips</a>. - New in the WordPress mobile app: Prompts - A good name is short and memorable.\nYou can change it later. Views & Visitors Removed as featured image Set as featured image @@ -292,8 +292,9 @@ Language: en_CA Replace current featured image? Dismiss We’ll be removing the Classic Editor for new posts soon, but this won’t affect editing any of your existing posts or pages. Get a head start by enabling the Block Editor now in site settings. - OK - http(s):// + Try the new Block Editor + Edit %s block + Saving Retry all Remove upload Retry @@ -301,11 +302,8 @@ Language: en_CA No Yes Cancel - Try the new Block Editor - Edit %s block - Saving - OK - Please wait until all files have been saved + OK + http(s):// Insert link Beta Editor is still loading @@ -316,6 +314,8 @@ Language: en_CA Pick a media from gallery Take Photo or Video with camera %dpx + OK + Please wait until all files have been saved Files saving Content Cast the movie of your life. @@ -324,14 +324,22 @@ Language: en_CA Note: We’ll show you a new prompt each day on your dashboard to help get those creative juices flowing! The best way to become a better writer is to build a writing habit and share with others - that’s where Prompts come in! - Posting regularly attracts new readers. Tell us when you want to write and we’ll send you a reminder! Set reminders + Posting regularly attracts new readers. Tell us when you want to write and we’ll send you a reminder! Become a better writer by building a habit Writing & Poetry Travel Technology Sports Real Estate + Politics + Photography + Personal + People + Parenting + News + Music + Local Services Lifestyle Interior Design Health @@ -344,35 +352,27 @@ Language: en_CA DIY Education Community & Non-Profit - Politics - Photography - Personal - People - Parenting - News - Music - Local Services - Automotive - Art - Site topic - Tap <b>%1$s</b> to continue. - View more prompts Business Books Beauty + Automotive + Art E.g. Fashion, Poetry, Politics + Site topic + Tap <b>%1$s</b> to continue. Skip for today + View more prompts + %d answers Share blogging prompt ✓ Answered - %d answers Answer prompt Prompts All This colour combination may be hard for people to read. Try using a brighter background colour and/or a darker text colour. This colour combination may be hard for people to read. Try using a darker background colour and/or a brighter text colour. Failed to insert media.\nTap for more info. - What’s your website about? Choose a topic from the list below or type your own. + What’s your website about? Weekly Roundup Home Adding category @@ -383,173 +383,173 @@ Language: en_CA XML-RPC services are disabled on this site. Menu Your search includes characters not supported in WordPress.com domains. The following characters are allowed: A–Z, a–z, 0–9. - An error occurred while updating the notification content Check your internet connection and refresh the page. - Today\'s Stats Go to stats + Today\'s Stats + An error occurred while updating the notification content Edit Failed to moderate comments - Mark as Spam Move to Trash + Mark as Spam Unapprove - Navigates to layout selection screen Tiled gallery settings + Navigates to layout selection screen Gallery style - You can connect your Facebook account on the WordPress.com website. When you\'re done, return to the WordPress app to change your Sharing settings. Go to web + You can connect your Facebook account on the WordPress.com website. When you\'re done, return to the WordPress app to change your Sharing settings. App icon Back icon Automattic logo WordPress - Day One - Jetpack - Pocket Casts - Privacy Policy + WooCommerce + Tumblr Simplenote + Pocket Casts + Jetpack + Day One Source Code + Privacy Policy Terms of Service - Tumblr - WooCommerce Work from Anywhere + Work With Us Automattic Family - Instagram Legal and More + Twitter + Instagram Rate Us Share with Friends - Twitter - Work With Us You can edit this block using the web version of the editor. - Note: You must allow WordPress.com login to edit this block in the mobile editor. Open Jetpack Security settings - ADD MEDIA - Address Settings + Note: You must allow WordPress.com login to edit this block in the mobile editor. Note: Layout may vary between themes and screen sizes + Address Settings + ADD MEDIA We\'re having trouble loading your site\'s data at the moment. - Video not uploaded! Uploading videos longer than 5 minutes requires a paid plan. + Some data hasn\'t loaded The dashboard is not updated. Please check your connection and then pull to refresh. Couldn\'t update dashboard. - Some data hasn\'t loaded + Video not uploaded! Uploading videos longer than 5 minutes requires a paid plan. Acknowledgements California Privacy Notice + Version %1$s Acknowledgements Legal and More About %1$s - Version %1$s Blog - Double tap to select font size - Font Size - Get support - More support options - Selected: Default The basics - %1$s (%2$s) - Contact support + Selected: Default + More support options + Get support + Font Size + Double tap to select font size Double tap to select default font size - Be the first to comment + Contact support + %1$s (%2$s) Follow Conversation - There was an error getting post data + Be the first to comment View all comments - Follow conversation settings + There was an error getting post data There was an error getting comments - Copy URL from the clipboard, %s - Featured Image + Follow conversation settings From clipboard + Featured Image + Copy URL from the clipboard, %s About WordPress - Go to drafts Go to scheduled posts - Copy link - Author - Switched to HTML mode - Switched to Visual mode + Go to drafts + Create a post Posting regularly helps build your audience! Create your next post - Create a post + Switched to Visual mode + Switched to HTML mode Link copied to clipboard + Author + Copy link Adding a custom domain makes it easy for visitors to find your site Add your domain - Untitled - Create your first post Posts appear on your blog page in reverse chronological order. It\'s time to share your ideas with the world! + Create your first post + Untitled Upcoming scheduled posts Work on a draft post <span style=\"color:#008000;\">Free for the first year </span><span style=\"color:#50575e;\"><s>%s /year</s></span> Your domains will redirect to your site at %s Create link - Congratulations on your purchase! Your new domain <b>%s</b> is being set up. It may take up to 30 minutes for your domain to start working. + Congratulations on your purchase! + Select domain Domains Sticky - Select domain - Mark as sticky Stick post to the front page + Mark as sticky + Unfollow conversation Enable in-app notifications You\'re following this conversation. You will receive notifications by email when new comments are published. - Unfollow conversation Manage follow conversation options, Popup window - Could not enable in-app notifications Could not disable in-app notifications - Following this conversation\nEnable in-app notifications? + Could not enable in-app notifications + In-app notifications disabled In-app notifications enabled Unsubscribed from this conversation - In-app notifications disabled + Following this conversation\nEnable in-app notifications? + Search for a domain Domains purchased on this site will redirect visitors to <b>%s</b> You have a free one-year domain registration included with your plan - Search for a domain - Add a domain - Manage Domains Claim your free domain + Manage Domains + Add a domain <span style=\"color:#d63638;\">Expires on %s</span> - Primary site address - Change site address Expires on %s Your site domains - %s<span style=\"color:#50575e;\"> /year</span> - <span style=\"color:#B26200;\">%1$s for the first year </span><span style=\"color:#50575e;\"><s>%2$s /year</s></span> + Primary site address + Change site address Your free WordPress.com address is + <span style=\"color:#B26200;\">%1$s for the first year </span><span style=\"color:#50575e;\"><s>%2$s /year</s></span> + %s<span style=\"color:#50575e;\"> /year</span> Do you want to discard them? There are unsaved changes - Comment Comment cannot be empty - Email address - Done User email not valid - Name + Web address not valid User name cannot be empty + Email address Web address - Web address not valid + Comment + Name + Done Embed block previews are coming soon Weekly Roundup - Double tap to view embed options. Embed options + Double tap to view embed options. Site created! Complete another task. - <a href=\"\">1 blogger</a> likes this. <a href=\"\">%1$s bloggers</a> like this. - <a href=\"\">You and 1 blogger</a> like this. + <a href=\"\">1 blogger</a> likes this. <a href=\"\">You and %1$s bloggers</a> like this. + <a href=\"\">You and 1 blogger</a> like this. <a href=\"\">You</a> like this. + Line Height Get your domain %s - Line Height Unknown error fetching recommend app template - Share WordPress with a friend - Domains - Quick Links Invalid response received No response received Automattic Apps - Apps for any screen - You\'ll get reminders to blog <b>everyday</b> at <b>%s</b>. - Notification time + Share WordPress with a friend + Quick Links + Domains Weekly Roundup: %s + Notification time + You\'ll get reminders to blog <b>everyday</b> at <b>%s</b>. %1$s a week at %2$s Text formatting controls are located within the toolbar positioned above the keyboard while editing a text block + Selected: %s Select a colour above - How to edit your page - How to edit your post - Move blocks Navigates to select %s - Selected: %s - Changes to featured image will not be affected by the undo/redo buttons. + Move blocks + How to edit your post + How to edit your page Customize blocks + Changes to featured image will not be affected by the undo/redo buttons. Applies the setting You can rearrange blocks by tapping a block and then tapping the up and down arrows that appear on the bottom left side of the block to move it above or below other blocks. Welcome to the world of blocks @@ -583,8 +583,8 @@ Language: en_CA Unable to embed media Try another search term No blocks found - %s embed block previews are coming soon %s previews not yet available + %s embed block previews are coming soon Double tap to preview post. Double tap to preview page. Shown in your visitor\'s browser tab and other places online. @@ -605,10 +605,10 @@ Language: en_CA You can update this anytime Select the days you want to blog on You can update this anytime via My Site > Settings > Blogging reminders. - Reminders removed! - All set! You have no reminders set. You\'ll get reminders to blog %1$s a week on %2$s at %3$s. + Reminders removed! + All set! Update None set %s a week @@ -624,10 +624,10 @@ Language: en_CA Done Notify me <a href=\"%1$s\">Enter your server credentials</a> to enable one click site restores from backups. + Set as Featured Image + Remove as Featured Image Create category WordPress for Android support - Remove as Featured Image - Set as Featured Image Manage your site\'s categories Categories The content of your latest posts page is automatically generated and cannot be edited. @@ -653,8 +653,8 @@ Language: en_CA Double tap to open action sheet to add image or video Current unit is %s Crosspost - Columns Settings %s converted to regular block + Columns Settings Add link to %s Add link text Add image or video @@ -674,11 +674,11 @@ Language: en_CA Move Image Forward Move Image Backward Width settings - Column Settings Link Rel + Column Settings + (Untitled) Site User profile bottom sheet information - (Untitled) Likes list %s Two Three @@ -693,10 +693,10 @@ Language: en_CA No preview available Text colour Padding - Featured Four - Create embed + Featured Custom URL + Create embed Column %d Briefly describe the link to help screen reader user Add blocks @@ -706,10 +706,10 @@ Language: en_CA Transform block… Failed to insert media. Failed to insert audio file. + Describe the purpose of the image. Leave empty if the image is purely decorative. %1$s transformed to %2$s Error loading like data. %s. %d Likes - Describe the purpose of the image. Leave empty if the image is purely decorative. One Like Suggestion: Use icon button @@ -717,13 +717,13 @@ Language: en_CA Search button. Current button text is Search blocks Search block label. Current text is + Outside No custom placeholder set Inside Hide search heading Double tap to edit placeholder text Double tap to edit label text Double tap to edit button text - Outside double-tap to change unit Current placeholder text is Clear search @@ -735,8 +735,8 @@ Language: en_CA No network available. No unreplied comments Unreplied - Search settings ADD LINK + Search settings Always allowed IP addresses Disallowed comments Add button text @@ -749,42 +749,42 @@ Language: en_CA The scan found %1$s potential threats with %2$s. Please review them below and take action or tap the fix all button. We are %3$s if you need us. We\'re hard at work in the background fixing these threats. In the meantime feel free to continue to use your site as normal, you can check the progress at anytime. Edit focal point - Double tap to open Action Sheet to edit, replace, or clear the image Double tap to open Bottom Sheet to edit, replace, or clear the image + Double tap to open Action Sheet to edit, replace, or clear the image example.com Type a name for your site <b>All tasks completed</b><br/>You’ll reach more people. Nice job! <b>All tasks completed</b><br/>You’ve customized your site. Well done! - Once this invite link is disabled, nobody will be able to use it to join your team. Are you sure? - Didn\'t mean to create a new account? Go back to re-enter your email address. Hide for now + Didn\'t mean to create a new account? Go back to re-enter your email address. + Once this invite link is disabled, nobody will be able to use it to join your team. Are you sure? + Disable invite link Invalid response received + No response received There was an error getting data for role %1$s There was an error getting roles - Disable invite link Unknown error fetching invite links data Use this link to onboard your team members without having to invite them one by one. Anybody visiting this URL will be able to sign up to your organization, even if they received the link from somebody else, so make sure that you share it with trusted people. - No response received - Disable invite link Expires %1$s + Disable invite link + Share invite link Generate new link Refresh links status Invite Link - Share invite link - Threats found Threat found - <b>Scan Finished</b> <br> No threats found + Threats found <b>Scan Finished</b> <br> %s potential threats found <b>Scan Finished</b> <br> One potential threat found - Disable + <b>Scan Finished</b> <br> No threats found Fixing Threat - Check your pages and make changes, or add or remove pages. + Disable Unpin this + Check your pages and make changes, or add or remove pages. + View your site Discover and follow sites that inspire you. + Social sharing Automatically share new posts to your social media. Give your site a name that reflects its personality and topic. - Social sharing - View your site Check your site stats We\'ll still attempt to create your downloadable backup file. We couldn\'t find the status to say how long your downloadable backup will take. @@ -816,6 +816,7 @@ Language: en_CA Double tap to listen the audio file Choose audio Audio Player + audio file Audio caption. %s Audio caption. Empty ADD AUDIO @@ -823,7 +824,6 @@ Language: en_CA Use this audio Choose audio from device Optional: enter a custom message to be sent with your invitation. - audio file Learn more about roles Fixed Found @@ -834,8 +834,8 @@ Language: en_CA Welcome to Jetpack Scan, we are taking a first look at your site now and the results will be with you soon. We\'re hard at work in the background fixing this threat. In the meantime feel free to continue to use your site as normal, you can check the progress at anytime. We will send you a notification if a threat is found. In the meantime, feel free to continue to use your site as normal, you can check the progress at anytime. - Jetpack Scan couldn\'t complete a scan of your site. Please check to see if your site is down – if it\'s not, try again. If it is, or if Jetpack Scan is still having problems, contact our support team. Fixing Threats + Jetpack Scan couldn\'t complete a scan of your site. Please check to see if your site is down – if it\'s not, try again. If it is, or if Jetpack Scan is still having problems, contact our support team. Something went wrong Backing up site Backing up site from %1$s %2$s @@ -875,11 +875,11 @@ Language: en_CA Tablet Mobile Don\'t show again + Pin this Select %1$s Pages %2$s to see your page list. Change, add, or remove your site\'s pages. Review site pages Select %1$s Homepage %2$s to edit your Homepage. - Pin this Mark as unseen Mark as seen Media upload failed.\n%1$s @@ -888,8 +888,8 @@ Language: en_CA Marked post as unseen Marked post as seen Error getting fix status. Please contact our support. - Error fixing threats. Please contact our support. Threat was successfully fixed. + Error fixing threats. Please contact our support. Please confirm you want to fix one active threat. Fix all threats Error ignoring threat. Please contact support. @@ -925,10 +925,10 @@ Language: en_CA We successfully created a backup of your site from %1$s %2$s. Your backup is now available for download Your Backup + No need to wait around. We\'ll notify you when your backup is ready. Creating downloadable backup icon We\'re creating a downloadable backup of your site from %1$s %2$s. Currently creating a downloadable backup of your site - No need to wait around. We\'ll notify you when your backup is ready. Download Backup There is another download running. There was a problem handling the request. Please try again later. @@ -964,17 +964,17 @@ Language: en_CA Threat found %s Vulnerability found in WordPress Miscellaneous vulnerability - %s: malicious code pattern - Database %s threats Vulnerable Theme: %1$s (version %2$s) Vulnerable Plugin: %1$s (version %2$s) + %s: malicious code pattern + Database %s threats %s: infected core file Threat found Fix All - this site a few seconds ago %s minute(s) ago %s hour(s) ago + this site The last Jetpack scan ran %1$s and did not find any risks. %2$s Your site may be at risk Don\'t worry about a thing @@ -983,11 +983,11 @@ Language: en_CA Scan state icon Backup Activity Type filter (%s types selected) + %1$s (showing %2$s items) Activity Type filter No activities recorded in the selected date range. No activities available Please check your internet connection and retry. - %1$s (showing %2$s items) No connection Activity Type (%s) Date Range filter @@ -1052,10 +1052,10 @@ Language: en_CA Done Next Delete + There was an error while selecting the theme. + Please check your internet connection and retry. Tap retry when you\'re back online. Layouts not available while offline - Please check your internet connection and retry. - There was an error while selecting the theme. Continue with store credentials Find your connected email Follow topics @@ -1082,21 +1082,21 @@ Language: en_CA The World\'s Best Fans My Top Ten Cafes Politics - Gardening Music + Gardening Football Cooking Art Rock n\' Roll Weekly Web News - I am so inspired by photographer Cameron Karsten’s work. I will be trying these techniques on my next Pamela Nguyen + I am so inspired by photographer Cameron Karsten’s work. I will be trying these techniques on my next Getting Inspired + Follow your favourite sites and discover new blogs. Watch your audience grow with in-depth analytics. - With the powerful editor you can post on the go. See comments and notifications in real time. + With the powerful editor you can post on the go. Welcome to the world’s most popular website builder. - Follow your favourite sites and discover new blogs. Media loading failed Sites to follow We are working hard to add more blocks with each release. @@ -1104,28 +1104,28 @@ Language: en_CA Help button Edit using web editor Choose images - They’re published as a new blog post on your site so your audience never misses out on a thing. Create Story Post + They’re published as a new blog post on your site so your audience never misses out on a thing. Story posts don\'t disappear Combine photos, videos, and text to create engaging and tappable story posts that your visitors will love. - Blank page created - Page created - %1$s was denied access to your photos. To fix this, edit your permissions and turn on %2$s and %3$s. Now stories are for everyone Example story title How to create a story post Introducing Story Posts + Blank page created + Page created + %1$s was denied access to your photos. To fix this, edit your permissions and turn on %2$s and %3$s. + Media insert failed. Media insert failed: %s Choose from WordPress Media Library - Media insert failed. Back Get Started Follow topics to discover new blogs By This referrer can\'t be marked as spam - Open Website Unmark as Spam Mark as Spam + Open Website Uploading gif media Uploading stock media Uploading media @@ -1153,13 +1153,13 @@ Language: en_CA Internal server error occurred Your action is not allowed %1$s more items - Note: Column layout may vary between themes and screen sizes Select a layout - You might like - Hide + Note: Column layout may vary between themes and screen sizes + Create a post or story Create a page Create a post - Create a post or story + You might like + Hide Video caption. Empty Updates the title. Paste block after @@ -1170,15 +1170,15 @@ Language: en_CA Video could not be saved Error saving image Operation in progress, try again - View Storage Couldn\'t find Story slide + View Storage + We need to save the story on your device before it can be published. Review your storage settings and remove files to free up space. Insufficient device storage + Retry saving or delete the slides, then try publishing your story again. + Unable to save %1$d slides Unable to save 1 slide Manage %1$d slides require action - We need to save the story on your device before it can be published. Review your storage settings and remove files to free up space. - Retry saving or delete the slides, then try publishing your story again. - Unable to save %1$d slides 1 slide requires action Unable to upload \"%1$s\" Unable to upload \"%1$s\" @@ -1186,21 +1186,21 @@ Language: en_CA Uploading \"%1$s\"… %1$d slides remaining 1 slide remaining - Saving \"%1$s\"… several stories - This slide has not been saved yet. If you delete this slide, you will lose any edits you have made. - Change text alignment - errored - selected - unselected + Saving \"%1$s\"… Untitled Discard Your story post will not be saved as a draft. Discard story post? Delete + This slide has not been saved yet. If you delete this slide, you will lose any edits you have made. This slide will be removed from your story. Delete story slide? Change text colour + Change text alignment + errored + selected + unselected Slide Retry Saved @@ -1209,12 +1209,11 @@ Language: en_CA SHARE Saved to photos Retry - Get started by choosing from a wide variety of pre-made page layouts. Or just start with a blank page. - Tap %1$s Create. %2$s Then select <b>Blog post</b> Saved Saving Flash Flip + Sound Text Stickers Flash @@ -1223,28 +1222,29 @@ Language: en_CA Preview Create page Create blank page + Get started by choosing from a wide variety of pre-made page layouts. Or just start with a blank page. + Choose a layout Give your story a title Create a post or story Create a post, page or story - Sound - Choose a layout + Tap %1$s Create. %2$s Then select <b>Blog post</b> Choose from device + Story post Editing site icons on self-hosted WordPress sites requires the Jetpack plugin. Unable to find the linked page jump Cannot upload file.\nStorage quota was exceeded. Storage quota exceeded - Story post Add file Replace video Replace image or video - Choose image - Choose image or video + Convert to link Choose video + Choose image or video + Choose image Block removed + Enter your existing site address Signup confirmation If you continue with Google and don\'t already have a WordPress.com account, you are creating an account and you agree to our %1$sTerms of Service%2$s. - Enter your existing site address - Convert to link By continuing, you agree to our %1$sTerms of Service%2$s. We’ll use this email address to create your new WordPress.com account. We’ve emailed you a signup link to create your new WordPress.com account. Check your email on this device, and tap the link in the email you receive from WordPress.com. @@ -1256,18 +1256,19 @@ Language: en_CA Not seeing the email? Check your Spam or Junk Mail folder. Check your email on this device and tap the link in the email you received from WordPress.com. We\'ll email you a link that\'ll log you in instantly, no password needed. + Check email Get Started - Or type your password Enter your email address to log in or create a WordPress.com account. + Or type your password Create account Send link by email - Check email Reset your password There was a problem handling the request. Please try again later. - Tap <b>%1$s</b> to set a new title Check your site title + Tap <b>%1$s</b> to set a new title Trashing this post will also discard local changes, are you sure you want to continue? %s block options + Remove block Duplicate block Copy block Copied block @@ -1276,24 +1277,23 @@ Language: en_CA Block cut Block copied The Site Title can only be changed by a user with the administrator role. - Remove block The Site Title is displayed in the title bar of a web browser and is displayed in the header for most themes. Topic - Unsaved changes Couldn\'t update site title. Check your network connection and try again. + Unsaved changes Open link in a browser Navigates to the previous content sheet - Navigates to custom colour picker Navigates to customize the gradient + Navigates to custom colour picker Gradient Type Go back Double tap to select the option Customize Gradient Page author Media thumbnail could not be loaded - Me Content structure Everyone + Me Dismiss Not set Tags help tell readers what a post is about. @@ -1310,16 +1310,16 @@ Language: en_CA Move to Draft Trashed posts can\'t be edited. Do you want change the status of this post to \"draft\" so you can work on it? Move post to Drafts? + Choose your topics + Choose your topics Done Select a few to continue Published Trashed Scheduled - Read CCPA privacy notice Publish Date + Read CCPA privacy notice The California Consumer Privacy Act (\"CCPA\") requires us to provide California residents with some additional information about the categories of personal information we collect and share, where we get that personal information, and how and why we use it. - Choose your topics - Choose your topics Privacy notice for California users Status & Visibility Update Now @@ -1331,19 +1331,19 @@ Language: en_CA We cannot open pages at the moment. Please try again later Set as Posts Page Set as Homepage + %1$s is not a valid %2$s Select Page Posts Page Static Homepage Classic Blog Selected homepage and page for posts cannot be the same. - %1$s is not a valid %2$s - Homepage Settings + Homepage settings update failed, check your internet connection Cannot save homepage settings before pages are loaded - Accept Cannot save homepage settings + Accept Loading of pages failed Choose from a homepage that displays your latest posts (classic blog) or a fixed/static page. - Homepage settings update failed, check your internet connection + Homepage Settings Homepage Posts Page update failed Posts Page successfully updated @@ -1355,16 +1355,16 @@ Language: en_CA Double tap to go to colour settings When you follow sites, you\'ll see their content here Find out more + What\'s New In %s Insert %d crop - Preview Image Thumbnail Failed to load into file, please try again. + Preview Image Thumbnail Use this media Use this video Choose media Choose video Couldn\'t select site. Please try again. - What\'s New In %s Continue Reblog failed Manage Sites @@ -1379,19 +1379,19 @@ Language: en_CA Continue Copy Number of columns + Move block right from position %1$s to position %2$s Move block right Move block left from position %1$s to position %2$s Move block left Double tap to move the block to the right - Move block right from position %1$s to position %2$s Double tap to move the block to the left + Block settings Creating dashboard - Adding site features Setting up theme + Adding site features Grabbing site URL Your site will be ready shortly Hooray!\nAlmost done - Block settings Cancel upload There was a problem handling the request Powered by Tenor @@ -1399,9 +1399,9 @@ Language: en_CA Saturday Friday Thursday + Wednesday Tuesday Monday - Wednesday Sunday Failed to access content of a private site. Some media might be unavailable Accessing content of a private site @@ -1409,53 +1409,53 @@ Language: en_CA Failed to load image.\nPlease tap to retry. Preview Image Unknown page format + We couldn\'t complete this action, and didn\'t submit this page for review. We couldn\'t complete this action, and didn\'t schedule this page. We couldn\'t complete this action, and didn\'t publish this private page. - We couldn\'t complete this action, and didn\'t submit this page for review. + We couldn\'t complete this action, and didn\'t publish this page. We couldn\'t submit this page for review, but we\'ll try again later. We couldn\'t schedule this page, but we\'ll try again later. - We couldn\'t publish this page, but we\'ll try again later. - We couldn\'t complete this action, and didn\'t publish this page. We couldn\'t publish this private page, but we\'ll try again later. + We couldn\'t publish this page, but we\'ll try again later. We couldn\'t upload this media, and didn\'t submit this page for review. We couldn\'t upload this media, and didn\'t schedule this page. We couldn\'t upload this media, and didn\'t publish this private page. + We couldn\'t upload this media, and didn\'t publish the page. We\'ll save your draft when your device is back online We\'ll publish your private page when your device is back online. - We couldn\'t upload this media, and didn\'t publish the page. - We\'ll submit your page for review when your device is back online. We\'ll schedule your page when your device is back online. + We\'ll submit your page for review when your device is back online. + We\'ll publish the page when your device is back online. Queued page - You\'ve made unsaved changes to this page Uploading page Device is offline. Page saved locally. - We\'ll publish the page when your device is back online. - Page saved on device - The page has failed media uploads and has been saved locally - Select blog for QuickPress shortcut + You\'ve made unsaved changes to this page Your page is uploading + The page has failed media uploads and has been saved locally + Page saved on device Page saved online + Select blog for QuickPress shortcut Set by Battery Saver Dark Light - You recently made changes to this page but didn\'t save them. Choose a version to load:\n\n Appearance + You recently made changes to this page but didn\'t save them. Choose a version to load:\n\n Show post content - Link To Only show excerpt + Link To Link Settings Excerpt length (words) Edit cover media CUSTOMIZE Button Link URL - Add paragraph block Border Radius + Add paragraph block Create a post Trashed Scheduled Published - Not Connected The Facebook connection cannot find any Pages. Jetpack Social cannot connect to Facebook Profiles, only published Pages. + Not Connected Likes Follows Comments @@ -1471,26 +1471,25 @@ Language: en_CA Select a Tag or Site, Pop Up Window Select a Site or Tag to filter posts Remove the current filter - Log in to WordPress.com Manage Topics & Sites - Log in to WordPress.com to see the latest posts from sites you follow + Log in to WordPress.com Log in to WordPress.com to see the latest posts from topics you follow + Log in to WordPress.com to see the latest posts from sites you follow + Replace Current Block Add To End Add To Beginning Add Block Before Add Block After - Follow a site - See the newest posts from sites you follow - Replace Current Block Add a topic + Follow a site You can follow posts on a specific subject by adding a topic - Filter + See the newest posts from sites you follow Following + Filter + Video caption. %s Edit video Edit media Add a shortcode… - Video caption. %s -   & %1$d %2$s Post author Create a post You have heard all stats for this period.\n Tapping again will restart from the beginning. @@ -1502,15 +1501,16 @@ Language: en_CA high medium low +   & %1$d %2$s %1$s, %2$d %3$s Gallery caption. %s Create a post or page Person building website Not right now Whatever you want to create or share, we’ll help you do it right here. - Image unselected Welcome to WordPress Photo library + Image unselected , Selected Image selected Image Thumbnail @@ -1528,21 +1528,21 @@ Language: en_CA We were unable to access the <b>XMLRPC file</b> on your site. You will need to reach out to your host to resolve this. Almost there! We just need to verify your Jetpack connected email address <b>%1$s</b> Log in with your %1$s site credentials - Following Site page - We cannot open the posts right now. Please try again later - %sB - %sM + Following + Likes + Discover + Saved + Topics + Sites + %sQi %sQa %sT - %sQi - Sites - Saved - Discover - Likes - We cannot load the data for your site right now. Please try again later + %sB + %sM %sK - Topics + We cannot open the posts right now. Please try again later + We cannot load the data for your site right now. Please try again later WordPress Media Library Unsupported Ungroup @@ -1568,12 +1568,12 @@ Language: en_CA Move block up Move block down from row %1$s to row %2$s Move block down + Link text Link inserted Image caption. %s Hide keyboard Help icon Double tap to undo last change - Link text Double tap to toggle setting Double tap to select an image Double tap to select a video @@ -1589,20 +1589,20 @@ Language: en_CA An unknown error occurred. Please try again. Alt Text ADD VIDEO + Add URL + Add alt text ADD IMAGE OR VIDEO ADD IMAGE ADD BLOCK HERE - Add URL - Add alt text Tap the Add to Save Posts button to save a post to your list. \"The list has loaded with %1$d items.\" Notifications Off On Turning Notifications for this site off will disable notifications display on notifications tab for this site. You can fine-tune which kind of notification you see after turning Notifications for this site on. + To see notifications on notifications tab for this site, turn Notifications for this site on. Enable notifications display on notifications tab for this site Disable notifications display on notifications tab for this site - To see notifications on notifications tab for this site, turn Notifications for this site on. Notifications for this site Notifications for this site Add image or video @@ -1631,11 +1631,11 @@ Language: en_CA You\'ve made unsaved changes to this post The version from this app The version from another device + From this app\nSaved on %1$s\n\nFrom another device\nSaved on %2$s\n You recently made changes to this post but didn\'t save them. Choose a version to load:\n\n Which version would you like to edit? Delete Permanently We won\'t save the latest changes to your draft. - From this app\nSaved on %1$s\n\nFrom another device\nSaved on %2$s\n We won\'t schedule these changes. We won\'t submit these changes for review. We won\'t publish these changes. @@ -1676,14 +1676,14 @@ Language: en_CA Site time zone (UTC) Desktop Default + Close Dialogue Select preview type Share Go back Go forward + \"%1$s\" scheduled for publishing on \"%2$s\" in your %3$s app \n %4$s WordPress Scheduled Post: \"%s\" \"%s\" will be published in 10 minutes - Close Dialogue - \"%1$s\" scheduled for publishing on \"%2$s\" in your %3$s app \n %4$s \"%s\" will be published in 1 hour \"%s\" has been published Scheduled post: 10 minute reminder @@ -1731,23 +1731,23 @@ Language: en_CA At a glance Today All-time - Colour - Colour Views this week Please log in to the WordPress app to add a widget. No network available Couldn\'t load data Type + Colour Select your site Dark Light + Colour Select your site Site All-time Views This Week Add widget - If you just registered a domain name, please wait until we finish setting it up and try again.\n\nIf not, looks like something went wrong and plugin feature might not be available for this site. It takes longer than usual to refresh plugin details. Please check again later. + If you just registered a domain name, please wait until we finish setting it up and try again.\n\nIf not, looks like something went wrong and plugin feature might not be available for this site. Province (Not Available) By registering this domain you agree to our %1$sterms and conditions%2$s Check your network connection and try again. @@ -1759,17 +1759,17 @@ Language: en_CA Password updated Update password Registering domain name… - Select Country Select Province + Select Country + Register domain Postal code + Province City Address 2 Address Country Country code Phone - Province - Register domain Organization (optional) For your convenience, we have pre-filled your WordPress.com\n contact information. Please review to be sure it’s the correct information you want to use for this domain. Domain contact information @@ -1788,17 +1788,17 @@ Language: en_CA Failed to insert media.\nPlease tap to retry. Your draft is uploading Uploading draft - An error occurred while restoring the post Drafts + An error occurred while restoring the post Backdated for: %s Only see the most relevant stats. Add and organise your insights below. Social Annual Site Stats - Register Domain + Follower Totals Domain suggestions couldn\'t be loaded Type a keyword for more ideas No suggestions found - Follower Totals + Register Domain Remove from insights Move down Move up @@ -1807,8 +1807,8 @@ Language: en_CA Post is being restored Post restored Post is being trashed - Local changes Trashing this post will also discard unsaved changes, are you sure you want to continue? + Local changes Move to Draft Switch to list view Switch to cards view @@ -1819,34 +1819,34 @@ Language: en_CA Please log in with your username and password. Please log in using your WordPress.com username instead of your email address. Avg words/post + Total words Avg likes/post Total likes + Avg comments/post Total comments Posts Year - The site at this address is not a WordPress site. For us to connect to it, the site must use WordPress. - Total words - Avg comments/post This Year + The site at this address is not a WordPress site. For us to connect to it, the site must use WordPress. Failed to check available domain credits Checking domain credits Register domain To install plugins, you need to have a custom domain associated with your site. Install plugin + You\'ll be able to customize the look and feel of your site later Publish on: %s Schedule for: %s Published on: %s Scheduled for: %s Recent Weeks Avg. Views Per Day + Views Period Months and Years Load more - Views - You\'ll be able to customize the look and feel of your site later + Today Best Hour Best Day - Today Showing stats for: No thanks Later @@ -1864,33 +1864,33 @@ Language: en_CA We cannot load Plans at the moment. Please try again later. Cannot load Plans No connection + Switch to block editor There was a problem loading your data, refresh your page to try again. Data not loaded Edit new posts and pages with the Block Editor Use Block Editor - Switch to block editor exit - Next Steps - Your visitors will see your icon in their browser. Add a custom icon for a polished, pro look. Grow your audience Customize your site + Next Steps Choose a unique site icon + Your visitors will see your icon in their browser. Add a custom icon for a polished, pro look. + Select %1$s Stats %2$s to see how your site is performing. Tap %1$s Your Site Icon %2$s to upload a new one Draft and publish a post. - Select %1$s Stats %2$s to see how your site is performing. Enable post sharing Automatically share new posts to your social media accounts. Check your site stats + Keep up to date with your site\'s performance. Removing Next Steps will hide all tours on this site. This action cannot be undone. Remove Next Steps Remove this - Keep up to date with your site\'s performance. Skip task Reminder Select next period Select previous period - Most Popular Time %1$s of views + Most Popular Time %1$s (%2$s) +%1$s (%2$s) Showing site preview @@ -1920,12 +1920,14 @@ Language: en_CA Updating post Discard Web Discard Local + Local\nSaved on %1$s\n\nWeb\nSaved on %2$s\n This post has two versions that are in conflict. Select the version you would like to discard.\n\n Resolve sync conflict - Local\nSaved on %1$s\n\nWeb\nSaved on %2$s\n No data for this period Remove location from media We cannot open the statistics at the moment. Please try again later + No media matching your search + Search to find GIFs to add to your Media Library! Views Author Authors @@ -1955,10 +1957,8 @@ Language: en_CA Share post Create post It’s been %1$s since %2$s was published. Here’s how the post performed so far: - No media matching your search - Search to find GIFs to add to your Media Library! - Tags and Categories It\'s been %1$s since %2$s was published. Get the ball rolling and increase your post views by sharing your post: + Tags and Categories All-time %1$s - %2$s Followers @@ -2009,8 +2009,8 @@ Language: en_CA Medium Thumbnail History - Pending review The selected page is not available + Pending review You don\'t have any trashed pages You don\'t have any scheduled pages You don\'t have any draft pages @@ -2018,15 +2018,15 @@ Language: en_CA Search pages No pages matching your search Delete Permanently - Move to Draft Move to Trash + Move to Draft Set parent View + Trashed Scheduled Drafts Published We\'ve made too many attempts to send an SMS verification code — take a break, and request a new one in a minute. - Trashed There\'s no WordPress.com account matching this Google account. No sites matching your search No sites matching your search @@ -2034,6 +2034,7 @@ Language: en_CA Page has been permanently deleted Page has been scheduled Page has been published + Page has been trashed Page has been moved to Drafts Top level Are you sure you want to delete page %s? @@ -2041,17 +2042,16 @@ Language: en_CA There was a problem changing the page status There was a problem deleting the page Set Parent - Page has been trashed tap here Create your site Get your site up and running. Doesn\'t it feel good to cross things off a list? View your site + Preview your site to see what your visitors will see. Share your site - Connect to your social media accounts – your site will automatically share new posts. Tap %1$s Sharing %2$s to continue Tap the %1$s Connections %2$s to add your social media accounts - Preview your site to see what your visitors will see. + Connect to your social media accounts – your site will automatically share new posts. Publish a post Tap %1$s Create Post %2$s to create a new post No thanks @@ -2059,8 +2059,8 @@ Language: en_CA Go Cancel Not now - You don\'t have any sites More + You don\'t have any sites No followed topics Add topics here to find posts about your favourite topics Log in to the WordPress.com account you used to connect Jetpack. @@ -2112,9 +2112,9 @@ Language: en_CA Restoring to %1$s %2$s Currently restoring your site Your site has been successfully restored - Activity Log action button Your site has been successfully restored\nRestored to %1$s %2$s Your site is being restored\nRestoring to %1$s %2$s + Activity Log action button Auto-managed Save this post, and come back to read it whenever you\'d like. It will only be available on this device — saved posts don\'t sync to your other devices. Save Posts for Later @@ -2130,13 +2130,13 @@ Language: en_CA Site address login Email address login Tap %s to save a post to your list. + No posts saved — yet! Post saved View All Remove from saved posts Add to saved posts Saved posts Removed - No posts saved — yet! Change site icon Cancel Remove @@ -2191,8 +2191,8 @@ Language: en_CA Followed Sites Person reading device with notifications People looking at graphs and charts - Are you sure you\'d like to permanently delete this post? %1$s on %2$s + Are you sure you\'d like to permanently delete this post? Important General Use this photo @@ -2208,6 +2208,7 @@ Language: en_CA Create Tag navigate up Notifications + Open external link show more photo delete @@ -2231,7 +2232,6 @@ Language: en_CA %s\'s profile picture check mark Signing up with Google… - Open external link Connection to Jetpack failed: %s You are already connected to Jetpack Visual Mode @@ -2267,8 +2267,8 @@ Language: en_CA Notifications Reader Me - Notification settings My Site + Notification settings Your avatar has been uploaded and will be available shortly. It looks like you turned off permissions required for this feature.<br/><br/>To change this, edit your permissions and make sure <strong>%s</strong> is enabled. Permissions @@ -2327,15 +2327,15 @@ Language: en_CA Sending email Retry Close + There was some trouble sending the email. You can retry now or close and try again later. Username + You can always log in with a link like the one you just used, but you can also set up a password if you prefer. Password (optional) Display Name Retry Revert There was some trouble updating your account. You can retry or revert your changes to continue. There was some trouble uploading your avatar. - There was some trouble sending the email. You can retry now or close and try again later. - You can always log in with a link like the one you just used, but you can also set up a password if you prefer. Needs update Search Plugins New @@ -2378,11 +2378,11 @@ Language: en_CA by %s Change photo Unable to load plugins + Pages Manage your site\'s tags Saving Deleting Permanently delete \'%s\' tag? - Pages A tag with this name already exists Add New Tag Description @@ -2501,8 +2501,8 @@ Language: en_CA File Name URL Alt text - Blink light Connect a site + Blink light Vibrate device Choose sound Sights and Sounds @@ -2517,8 +2517,8 @@ Language: en_CA Enable notifications Disable notifications Off - Maximum Video Size On + Maximum Video Size Maximum Image Size There was an error uploading the media in this post: %s. There was an error uploading this post: %s. @@ -2558,16 +2558,16 @@ Language: en_CA Enter the address of the WordPress site you\'d like to connect. Already logged in to WordPress.com Continue - Enter your WordPress.com password. Connect another site + Enter your WordPress.com password. Requesting log-in email It looks like this password is incorrect. Please double check your information and try again. Requesting a verification code via SMS. Text me a code instead Almost there! Please enter the verification code from your Authenticator app. + Open Mail Next Log in to WordPress.com using an email address to manage all your WordPress sites. - Open Mail Image optimization shrinks images for quicker uploading.\n\nYou can change this any time in site settings. Turn on image optimization? Leave off @@ -2715,11 +2715,11 @@ Language: en_CA Medium Low Uploaded + Upload Failed Deleted Deleting Uploading Queued - Upload Failed Image Quality All media uploads have been cancelled due to an unknown error. Please retry uploading Unknown post format @@ -2779,47 +2779,47 @@ Language: en_CA Comment approved! Like now - Follower Viewer + Follower No connection, couldn\'t save your profile - None - Left Right + Left + None Selected %1$d Couldn\'t retrieve site users - Follower Email Follower + Follower Fetching users… - Email Followers Viewers + Email Followers Followers Team Invite up to 10 email addresses and/or WordPress.com usernames. Those needing a username will be sent instructions on how to create one. If you remove this viewer, he or she will not be able to visit this site.\n\nWould you still like to remove this viewer? If removed, this follower will stop receiving notifications about this site, unless they re-follow.\n\nWould you still like to remove this follower? Since %1$s - Couldn\'t remove follower Couldn\'t remove viewer + Couldn\'t remove follower Couldn\'t retrieve site email followers Couldn\'t retrieve site followers Some media uploads have failed. You can\'t switch to HTML mode\n in this state. Remove all failed uploads and continue? - Visual editor Image thumbnail - Changes saved - Caption - Alt text - Link to + Visual editor Width + Link to + Alt text + Caption + Changes saved Discard unsaved changes? Stop uploading? An error occurred while inserting media You are currently uploading media. Please wait until this completes. Can\'t insert media directly in HTML mode. Please switch back to visual mode. Uploading gallery… - Invite sent successfully Tap to try again! - Invite sent but error(s) occurred! + Invite sent successfully %1$s: %2$s + Invite sent but error(s) occurred! An error occurred while trying to send the invite! Cannot send: There are invalid usernames or emails Cannot send: A username or email is invalid @@ -2827,8 +2827,8 @@ Language: en_CA Custom message Invite Usernames or emails - External Invite People + External Clear search history Clear search history? No results found for %s for your language @@ -2836,33 +2836,33 @@ Language: en_CA Related Post Links are disabled on the preview screen Send - If you remove %1$s, that user will no longer be able to access this site, but any content that was created by %1$s will remain on the site.\n\nWould you still like to remove this user? Successfully removed %1$s + If you remove %1$s, that user will no longer be able to access this site, but any content that was created by %1$s will remain on the site.\n\nWould you still like to remove this user? Remove %1$s - The sites in this list haven\'t posted anything recently - People Role + People + The sites in this list haven\'t posted anything recently Couldn\'t remove user Couldn\'t update user role Couldn\'t retrieve site viewers Error updating your Gravatar - Error locating the cropped image Error reloading your Gravatar + Error locating the cropped image Error cropping the image Checking email Currently unavailable. Please enter your password Logging in Shown publicly when you comment. Capture or select photo - Your posts, pages, and settings will be emailed to you at %s. - Plan Plans + Plan + Your posts, pages, and settings will be emailed to you at %s. Export your content - Exporting content… Export email sent! - You have active premium upgrades on your site. Please cancel your upgrades prior to deleting your site. - Show purchases + Exporting content… Checking purchases + Show purchases + You have active premium upgrades on your site. Please cancel your upgrades prior to deleting your site. Premium Upgrades Something went wrong. Could not request purchases. Deleting site… @@ -2871,15 +2871,15 @@ Language: en_CA Primary Domain There was an error in deleting your site. Please contact support for more assistance. Error deleting site - Please type in %1$s in the field below to confirm. Your site will then be gone forever. Export content + Please type in %1$s in the field below to confirm. Your site will then be gone forever. Confirm Delete Site Contact Support If you want a site but don\'t want any of the posts and pages you have now, our support team can delete your posts, pages, media and comments for you.\n\nThis will keep your site and URL active, but give you a fresh start on your content creation. Just contact us to have your current content cleared out. - Start your site over Let Us Help - App Settings + Start your site over Start Over + App Settings Remove failed uploads Advanced No trashed comments @@ -2887,34 +2887,34 @@ Language: en_CA No approved comments Skip Couldn\'t connect. Required XML-RPC methods are missing on the server. - Status - Video Centre - Chat - Gallery - Image - Link - Quote + Video + Status Standard - Information on WordPress.com courses and events (online & in-person). - Aside + Quote + Link + Image + Gallery + Chat Audio + Aside + Information on WordPress.com courses and events (online & in-person). Opportunities to participate in WordPress.com research & surveys. Tips for getting the most out of WordPress.com. Community - Replies to my comments - Suggestions Research - Site achievements + Suggestions + Replies to my comments Username mentions - Likes on my posts + Site achievements Site follows + Likes on my posts Likes on my comments Comments on my site %d items 1 item - Known users\' comments All users + Known users\' comments No comments %d comments per page 1 comment per page @@ -2924,11 +2924,11 @@ Language: en_CA Automatically approve everyone\'s comments. Automatically approve if the user has a previously approved comment Require manual approval for everyone\'s comments. - 1 day %d days - Click the verification link in the email sent to %1$s to confirm your new address - Primary site + 1 day Web address + Primary site + Click the verification link in the email sent to %1$s to confirm your new address You are currently uploading media. Please wait until this completes. Comments couldn\'t be refreshed at this time - showing older comments Set Featured Image @@ -2937,13 +2937,13 @@ Language: en_CA Permanently delete these comments? Permanently delete this comment? Delete - Comment deleted Restore + Comment deleted No spam comments - Could not load page All - Interface Language + Could not load page Off + Interface Language About the app Couldn\'t save your account settings Couldn\'t retrieve your account settings @@ -2951,20 +2951,20 @@ Language: en_CA Language code not recognised Allow comments to be nested in threads. Thread up to - Remove - Search Disabled + Search + Remove Original Size Your site is visible only to you and users you approve Your site is visible to everyone but asks search engines not to index it Your site is visible to everyone and may be indexed by search engines A few words about you… - Display name will default to your username if it is not set About me + Display name will default to your username if it is not set Public display name - My Profile - First name Last name + First name + My Profile Related post preview image Couldn\'t save site info Couldn\'t retrieve site info @@ -3019,13 +3019,13 @@ Language: en_CA %d levels Private Hidden - Delete Site Public + Delete Site Hold for Moderation Links in comments Automatically approve - Threading Paging + Threading Sort by Users must be logged in Must include name and email @@ -3035,22 +3035,22 @@ Language: en_CA Default Format Default Category Address - Site Title Tagline + Site Title Defaults for new posts - Account Writing - Newest first + Account General - Discussion - Privacy - Related Posts - Comments - Close after + Newest first Oldest first + Close after + Comments + Related Posts + Privacy + Discussion You don\'t have permission to upload media to the site - Never Unknown + Never This post no longer exists You\'re not authorized to view this post Unable to retrieve this post @@ -3062,22 +3062,22 @@ Language: en_CA Something went wrong. Could not activate theme by %1$s Thanks for choosing %1$s - View - Details - Support - DONE MANAGE SITE + DONE + Support + Details + View Try & Customize Activate - Current Theme - Details - Support Active + Support + Details Customize - Post published - Page published - Post updated + Current Theme Page updated + Post updated + Page published + Post published Sorry, no themes found. Load more posts No sites matched \'%s\' @@ -3110,279 +3110,279 @@ Language: en_CA Couldn\'t load notification settings Comment likes App notifications - Notifications tab Email + Notifications tab We\'ll always send important emails regarding your account, but you can get some helpful extras, too. Latest Post Summary No connection + Post sent to trash + Trash Stats Preview View - Edit Publish - Post sent to trash - Trash + Edit You are not authorized to access this site This site could not be found Undo The request has expired. Log in to WordPress.com to try again. - Best Views Ever Ignore + Best Views Ever Today\'s Stats All-time posts, views, and visitors Insights Log out of WordPress.com - Login/Logout Log in to WordPress.com - \"%s\" wasn\'t hidden because it\'s the current site + Login/Logout Account Settings + \"%s\" wasn\'t hidden because it\'s the current site Create WordPress.com site Add self-hosted site - Show/hide sites Add new site - View Admin - View Site + Show/hide sites Choose site + View Site + View Admin Switch Site - Look and Feel - Publish - Posts Site Settings + Posts + Publish + Look and Feel Configuration Tap to show them Deselect all - Show - Hide Select all - Language - Verification code - Invalid verification code + Hide + Show Log in again to continue. - Authors + Invalid verification code + Verification code + Language Unable to retrieve posts Could not open notification Unknown Search Terms Search Terms + Authors Fetching pages… Fetching posts… Fetching media… Application logs have been copied to the clipboard + This site is empty New posts An error occurred while copying text to clipboard Uploading post - This site is empty - Fetching themes… - %1$d months - A year %1$d years + A year + %1$d months A month - %1$d minutes - an hour ago - %1$d hours - A day %1$d days + A day + %1$d hours + an hour ago + %1$d minutes a minute ago seconds ago - Posts & Pages - Videos Followers + Videos + Posts & Pages Countries Likes - Years - Views Visitors + Views + Years + Fetching themes… Details %d selected - You don\'t have permission to view or edit posts - You don\'t have permission to view or edit pages Browse our FAQ No comments yet - View original article + No posts with this topic Like + View original article Comments are closed %1$d of %2$d Can\'t publish an empty post - Older than a month + You don\'t have permission to view or edit posts + You don\'t have permission to view or edit pages More - Older than 2 days + Older than a month Older than a week + Older than 2 days + Help & Support Liked Comment - No posts yet. Why not create one? - Reply to %s Comment trashed + Reply to %s + No posts yet. Why not create one? Logging out… - No posts with this topic - Help & Support Unable to perform this action Unable to block this site Posts from this site will no longer be shown Block this site - Update Schedule - Followed sites - Reader Site - Site followed - Unable to show this site - You already follow this site - Unable to follow this site - Unable to unfollow this site + Update No recommended sites - Followed topics + Unable to unfollow this site + Unable to follow this site + You already follow this site + Unable to show this site + Site followed Enter a URL or topic to follow - Help - Invalid SSL certificate + Followed sites + Followed topics + Reader Site If you usually connect to this site without problems, this error could mean that someone is trying to impersonate the site, and you shouldn\'t continue. Would you like to trust the certificate anyway? - There is no network available - The media item couldn\'t be retrieved - An error occurred when accessing this blog - Failed to fetch themes - Not spam - Adding category failed - Category added successfully - The category name field is required - A mounted SD card is required to upload media - No notifications - Posts couldn\'t be refreshed at this time - Pages couldn\'t be refreshed at this time - Comments couldn\'t be refreshed at this time - An error occurred - An error occurred while moderating - An error occurred while editing the comment - Couldn\'t load the comment - Error downloading image - Your email address isn\'t valid - Enter a valid email address + Invalid SSL certificate + Help The username or password you entered is incorrect + Enter a valid email address + Your email address isn\'t valid + Error downloading image + Couldn\'t load the comment + An error occurred while editing the comment + An error occurred while moderating + An error occurred + Comments couldn\'t be refreshed at this time + Pages couldn\'t be refreshed at this time + Posts couldn\'t be refreshed at this time An error occurred while deleting the post - Select categories - Connection error - Cancel edit - An error occurred when loading the post. Refresh your posts and try again. - Learn more - Thumbnail grid - You don\'t have permission to view the media library - Some media can\'t be deleted at this time. Try again later. - Link text (optional) - Create a link - Page settings - Local draft - Horizontal alignment - Post settings - Approved - Pending - Spam - Edit comment - Approve - Unapprove - Spam - Saving changes - Cancel editing this comment? - Comment is required - Comment hasn\'t changed - Remove site - View in browser - Add new category - Category name - Couldn\'t create temp file for media upload. Make sure there is enough free space on your device. - No notifications…yet. - New post - New media - Local changes - Image settings - WordPress blog - This blog is hidden and couldn\'t be loaded. Enable it again in settings and try again. - An error occurred while creating the app database. Try reinstalling the app. + No notifications + A mounted SD card is required to upload media + The category name field is required + Category added successfully + Adding category failed + Not spam + Failed to fetch themes + An error occurred when accessing this blog + The media item couldn\'t be retrieved + There is no network available + Unable to remove this topic + Unable to add this topic Application log + An error occurred while creating the app database. Try reinstalling the app. + This blog is hidden and couldn\'t be loaded. Enable it again in settings and try again. + Media couldn\'t be refreshed at this time + WordPress blog + Image settings + Local changes + New media + New post + No notifications…yet. Authorization required - Trashed - Trash - Send to trash? - Trash Check that the site URL entered is valid - Media couldn\'t be refreshed at this time + Couldn\'t create temp file for media upload. Make sure there is enough free space on your device. + Category name + Add new category + View in browser + Remove site + Comment hasn\'t changed + Comment is required + Cancel editing this comment? + Saving changes + Trash + Send to trash? + Trash + Spam + Unapprove + Approve + Edit comment + Trashed + Spam + Pending + Approved + Delete page? + Delete post? + Post settings Couldn\'t find the file for upload. Was it deleted or moved? + Horizontal alignment + Local draft + Page settings + Create a link + Link text (optional) + Some media can\'t be deleted at this time. Try again later. + You don\'t have permission to view the media library + Thumbnail grid + Learn more + An error occurred when loading the post. Refresh your posts and try again. An error occurred when accessing this plugin - Delete post? - Delete page? - Unable to add this topic - Unable to remove this topic + Cancel edit + Connection error + Select categories Share link Fetching posts… You and %,d others like this %,d people like this - Comment marked as spam You can\'t share to WordPress without a visible blog + Comment marked as spam Comment unapproved + Unable to retrieve this post You and one other like this - Select photo Select video - Unable to retrieve this post - This list is empty - (Untitled) - Share - Follow - Following - Reply to comment… - Added %s - Removed %s - One person likes this - You like this - Couldn\'t post your comment - Unable to share - Unable to view image - Unable to open %s - No comments yet - Reblog + Select photo Sign Up - You already follow this topic + Unable to open %s + Unable to view image + Unable to share That isn\'t a valid topic - Themes - Squares - Tiled - Circles - Slideshow - Title - Caption - Description - Failed to update - Activate - Share - Stats - Clicks - Referrers - Today - Yesterday - Days - Weeks + You already follow this topic + Couldn\'t post your comment + You like this + One person likes this + Removed %s + Added %s + Reply to comment… + Following + Follow + Share + Reblog + (Untitled) + No comments yet + This list is empty Months + Weeks + Days + Yesterday + Today + Referrers Tags & Categories + Clicks + Stats + Share + Activate + Failed to update + Description + Caption + Title + Slideshow + Circles + Tiled + Squares + Themes Discard Manage - Reply published - Follows - %d new notifications and %d more. + %d new notifications + Follows + Reply published Log in Loading… - HTTP username HTTP password + HTTP username An error occurred while uploading media Incorrect username or password. - Password - Username Log In + Username + Password Reader - Use as featured image Include image in post content - No network available - Pages - Caption (optional) + Use as featured image Width + Caption (optional) + Pages Posts Anonymous - OK + No network available done + OK URL Uploading… Alignment @@ -3395,27 +3395,27 @@ Language: en_CA Shortcut name can\'t be empty Private Title - Categories Separate tags with commas + Categories SD Card Required Media Category updated successfully - Delete Approve - None + Delete Updating category failed - Error - Cancel - Save - Add - Category refresh error - Preview - on + None + Publish Now Reply - Notification Settings - Yes + on + Preview + Category refresh error + Error No - Publish Now + Yes + Notification Settings + Add + Save + Cancel Once Twice diff --git a/WordPress/src/main/res/values-es/strings.xml b/WordPress/src/main/res/values-es/strings.xml index e92946008ce3..ac2fc8accbc4 100644 --- a/WordPress/src/main/res/values-es/strings.xml +++ b/WordPress/src/main/res/values-es/strings.xml @@ -19,40 +19,40 @@ Language: es Este sitio %1$s usa %2$s, que todavía no es compatible con todas las funciones de la aplicación. Instala el %3$s. %1$s usa %2$s, que todavía no es compatible con todas las funciones de la aplicación. Instala el %3$s. - Pásate a la aplicación de Jetpack en pocos días. El cambio es gratuito y solo te llevará un minuto. + Pásate a la aplicación de Jetpack en pocos días. Hemos eliminado algunas funciones (como Estadísticas, Lector o Notificaciones, entre otras) de la aplicación de WordPress y, ahora, solo están disponibles en la de Jetpack. + Tráfico + Contenido + Hecho Encontrarás más información en Jetpack.com Cambiar a la aplicación de Jetpack %s se han trasladado a la aplicación de Jetpack. %s se ha trasladado a la aplicación de Jetpack. WP Admin - Gestionar - Tráfico - Contenido Configurar - Hecho Ahora que Jetpack está instalado, solo tenemos que configurarlo. Solo te llevará un minuto. - Promocionar una entrada con Blaze ahora + Gestionar Promocionar esta página con Blaze Promocionar esta entrada con Blaze + Promocionar una entrada con Blaze ahora Inicia y detén la actividad promocional con Blaze y haz un seguimiento del rendimiento siempre que quieras. Tu contenido aparecerá en millones de sitios web de WordPress y Tumblr. Comienza a promocionar cualquier entrada o página en cuestión de minutos y a un precio muy asequible. Genera más tráfico hacia tu sitio con Blaze - Blaze Este dominio ya está registrado Oferta Recomendado Mejor alternativa - %s al año Ayuda - Con nuestras preguntas frecuentes podrás resolver algunas de tus dudas. ¡Gracias por cambiar a la aplicación Jetpack! Registros Entradas Gratis Ayuda + Blaze + %s al año + Con nuestras preguntas frecuentes podrás resolver algunas de tus dudas. Menú de bloques Ocultar esto Muestra tu trabajo en millones de sitios @@ -68,20 +68,20 @@ Language: es %1$s usa %2$s, que todavía no es compatible con todas las funciones de la aplicación.\n\nInstala el %3$s para usar la aplicación con este sitio. Instala el plugin completo de Jetpack Solo hay un sitio disponible, por lo que no puedes cambiar tu sitio principal. - Contactar con soporte Reintentar En estos momentos, no se puede instalar Jetpack. Se ha producido un problema Icono de error + Contactar con soporte + Promocionar con Blaze + Instalar Jetpack Todo listo para usar este sitio con la aplicación. Jetpack instalado Instala Jetpack en tu sitio. Esto puede llevar unos minutos completarse. Instalando Jetpack Continuar Las credenciales de tu web no se almacenarán y solo se usarán para instalar Jetpack. - Instalar Jetpack Icono de Jetpack - Promocionar con Blaze Libera todo el potencial de tu sitio. Obtén estadísticas, notificaciones y más con Jetpack. Tu sitio tiene el plugin de Jetpack La aplicación móvil Jetpack está diseñada para funcionar junto con el plugin de Jetpack. Haz el cambio ahora y obtén acceso a estadísticas, notificaciones o el lector, entre otras funciones. @@ -116,8 +116,8 @@ Language: es %1$s es mayor que la semana anterior Tus visitantes en los últimos siete días son %1$s menos que en los siete días anteriores. Tus visitantes en los últimos siete días son %1$s más que en los siete días anteriores. - Tus visitas en los últimos siete días son %1$s menos que en los siete días anteriores. Tus visitas en los últimos siete días son %1$s más que en los siete días anteriores. + Tus visitas en los últimos siete días son %1$s menos que en los siete días anteriores. Siete días anteriores Últimos siete días %d semanas @@ -125,12 +125,12 @@ Language: es Desde el <b>DayOne</b> Ocultar esto Recuérdamelo más tarde - Algunas funciones, como estadísticas, lector o avisos, se trasladarán pronto a la aplicación móvil de Jetpack. Cambiar a la aplicación de Jetpack Más información en jetpack.com El cambio es gratuito y solo lleva un minuto. Pronto se van a retirar de la aplicación de WordPress las estadísticas, lectura, avisos y otras funcionalidades de Jetpack. Se van a retirar de la aplicación de WordPress las estadísticas, lectura, avisos y otras funcionalidades de Jetpack el %s. + Algunas funciones, como estadísticas, lector o avisos, se trasladarán pronto a la aplicación móvil de Jetpack. Las funciones de Jetpack se trasladarán pronto. Los avisos se están trasladando a la aplicación de Jetpack El lector se está trasladando a la aplicación de Jetpack @@ -155,8 +155,8 @@ Language: es Actualizando la categoría Actualizar categoría Las entradas de este usuario no volverán a mostrarse - Bloquear usuario Denunciar a este usuario + Bloquear usuario Abrir enlaces en WordPress Parece que tienes instalada la aplicación de Jetpack.\n\n¿Quieres abrir enlaces en la aplicación de Jetpack en el futuro?\n\nPuedes cambiar esta opción en cualquier momento desde Ajustes de la aplicación > Abrir enlaces en Jetpack. ¿Quieres abrir enlaces en Jetpack? @@ -231,8 +231,8 @@ Language: es Las estadísticas funcionan con Jetpack Encuentra, sigue y dale «Me gusta» a todos tus sitios y publicaciones favoritos con Reader, ahora disponible en la nueva aplicación Jetpack. Reader funciona con Jetpack - La nueva app de Jetpack tiene estadísticas, lector, avisos, y más para mejorar tu WordPress. WordPress es mejor con Jetpack + La nueva app de Jetpack tiene estadísticas, lector, avisos, y más para mejorar tu WordPress. Actualiza tu plan para usar fondos de vídeo Actualiza tu plan para subir audio Funciona gracias a Jetpack @@ -244,8 +244,8 @@ Language: es Prueba la nueva aplicación Jetpack Problema al mostrar el bloque. \nToca para intentar la recuperación del bloque. La semana pasada tuviste %1$s visitas y %2$s comentarios - La semana pasada tuviste %1$s visitas y %2$s Me gusta La semana pasada tuviste %1$s visitas. + La semana pasada tuviste %1$s visitas y %2$s Me gusta La semana pasada tuviste %1$s visitas, %2$s Me gusta y %3$s comentarios. ⭐️ Tu última entrada %1$s ha recibido %2$s Me gusta. Funciona gracias a Jetpack @@ -279,16 +279,16 @@ Language: es Se están cargando los estímulos para bloguear. Espera un momento e inténtalo de nuevo. ¿No puedes decidirte? Puedes cambiar el tema en cualquier momento. Bloguear - Elegido para ti - Ideal para %s - Vista previa del tema %s Elige un tema - Me he saltado el estímulo para bloguear de hoy - Más información Totales Otros Buscar WordPress + Elegido para ti + Ideal para %s + Vista previa del tema %s + Me he saltado el estímulo para bloguear de hoy + Más información Vistas Programar Programa tu entrada @@ -296,10 +296,10 @@ Language: es Configura tus recordatorios de blogueo Consulta el curso Haz crecer tu audiencia - También puedes reorganizar los bloques tocando un bloque y luego tocando las flechas arriba y abajo que aparecen en la parte inferior izquierda del bloque para moverlo encima o debajo de otros bloques. Archivo de imagen no encontrado. Arrastrar y soltar hace que reordenar bloques sea algo trivial. Presiona y sujeta un bloque, luego arrástralo a su nueva ubicación y suéltalo. Arrastrar y soltar + También puedes reorganizar los bloques tocando un bloque y luego tocando las flechas arriba y abajo que aparecen en la parte inferior izquierda del bloque para moverlo encima o debajo de otros bloques. Botones de flechas %1$s. Seleccionado actualmente: %2$s Todas las tareas están completas @@ -307,23 +307,25 @@ Language: es Explorar código de acceso ⭐️ Tu última entrada %1$s ha recibido %2$s me gusta. No hay suficiente actividad. ¡Vuelve a comprobarlo más tarde, cuando tu sitio haya tenido más visitas! - %1$s, %2$s%% del total de seguidores %1$s (%2$s%%) + %1$s, %2$s%% del total de seguidores Copiar enlace - ¡Enhorabuena! Ya sabes manejarte<br/> + Sube fotos o vídeos Conoce la aplicación + ¡Enhorabuena! Ya sabes manejarte<br/> Sube los medios directamente a tu sitio desde tu dispositivo o cámara - Sube fotos o vídeos Obtén actualizaciones en tiempo real desde tu bolsillo - Selecciona %1$s Medios %2$s para ver tu biblioteca actual. Obtén actualizaciones en tiempo real desde tu bolsillo. Comprueba tus avisos + Utiliza <b> Descubrir </b> para encontrar sitios y etiquetas. + Miniatura de vídeo + Selecciona %1$s Medios %2$s para ver tu biblioteca actual. Selecciona la %1$s Pestaña de avisos %2$s para recibir actualizaciones sobre la marcha. Selecciona %1$s Más %2$s para subir medios. Puedes añadirlos a tus entradas o páginas desde cualquier dispositivo. - Utiliza <b> Descubrir </b> para encontrar sitios y etiquetas. Utiliza <b> Descubrir </b> para encontrar sitios y etiquetas. Prueba a seleccionar %1$s Ajustes %2$s para añadir temáticas que te gusten. - Miniatura de vídeo Principales comentaristas + Total de seguidores + Total de comentarios Publicada hace %1$d años Publicada hace un año Publicada hace %1$d meses @@ -335,35 +337,33 @@ Language: es Publicada hace %1$d minutos Publicada hace un minuto Publicada hace unos segundos - Total de seguidores - Total de comentarios Total de «Me gusta» Descartar Responder - Estímulo diario Entendido Toca <b>%1$s</b> para ver tu sitio + Estímulo diario Selecciona el %1$s Lector %2$s para descubrir otros sitios. - Aprende más sobre los estímulos Vídeo no seleccionado Vídeo seleccionado + Aprende más sobre los estímulos Miniatura del medio 🔥 La hora más popular %1$s %2$s Visitar el escritorio Tu sitio ya está protegido con VaultPress. Más abajo, puedes encontrar un enlace a tu escritorio de VaultPress. - Tu sitio tiene VaultPress Idioma actual: + Tu sitio tiene VaultPress Crear sitio Añadir bloques Pantalla inicial Más información Conviértete en un mejor escritor creando un hábito de escritura. Toca para más información. + Nombre del sitio Nuevo en la aplicación móvil de WordPress: Mensajes Un buen nombre es corto y fácil de recordar.\nPuedes cambiarlo más adelante. - Dale un nombre a tu web %s - Nombre del sitio ¿Te interesa crear tu audiencia? Echa un vistazo a nuestros <a href=\"%1$s\">mejores consejos</a>. + Dale un nombre a tu web %s Vistas y visitantes Eliminada como imagen destacada Establecer como imagen destacada @@ -405,16 +405,16 @@ Language: es Nota: ¡Te mostraremos un nuevo estímulo cada día en tu escritorio para ayudarte a que fluyan esos fluidos creativos! El mejor modo de convertirte en un mejor escritor es crear un hábito de escritura y compartir con otros - ¡aquí es donde entran los estímulos! - Presentando\nEstímulos para bloguear Configurar recordatorios - Incluir el estímulo para bloquear Publicar con regularidad atrae nuevos lectores. ¡Cuéntanos cuándo quieres escribir y te enviaremos un recordatorio! - Conviértete en un mejor escritor creando un hábito + Presentando\nEstímulos para bloguear + Incluir el estímulo para bloquear Escritura y poesía Viajes Tecnología Deportes Inmobiliaria + Conviértete en un mejor escritor creando un hábito Política Fotografía Personal @@ -440,114 +440,114 @@ Language: es Belleza Automoción Arte - Ej.: Moda, poesía, política Temática del sitio + Ver más estímulos Toca <b>%1$s</b> para continuar. + Ej.: Moda, poesía, política Omitir por hoy - Ver más estímulos - %d respuestas Comparte el estímulo de bloguear ✓ Respondido - Responder estímulo + %d respuestas Estímulos Todos + Responder estímulo Esta combinación de color puede ser difícil de leer para la gente. Intenta usar un color de fondo más claro y/o un color de texto más oscuro. - Esta combinación de color puede ser difícil de leer para la gente. Intenta usar un color de fondo más oscuro y/o un color de texto más claro. Fallo al insertar los medios.\nToca para más información. - Elige una temática de las listadas a continuación o escribe la tuya propia. + Esta combinación de color puede ser difícil de leer para la gente. Intenta usar un color de fondo más oscuro y/o un color de texto más claro. ¿De qué trata tu web? - Resumen semanal - Inicio + Elige una temática de las listadas a continuación o escribe la tuya propia. Añadir categorías - ¿Qué aplicación de correo electrónico usas? + Inicio + Resumen semanal Ha habido un problema al comunicar con el sitio. Se ha devuelto un código de error HTTP 401. - Las llamadas XML-RPC parecen bloqueadas en este sitio (código de error 401). Si el intento de acceso falla, toca en el icono de ayuda para ver las FAQ. + ¿Qué aplicación de correo electrónico usas? No se ha podido leer el sitio WordPress en esa URL. Toca en el icono de ayuda para ver las FAQ. + Las llamadas XML-RPC parecen bloqueadas en este sitio (código de error 401). Si el intento de acceso falla, toca en el icono de ayuda para ver las FAQ. Los servicios XML-RPC están desactivados en este sitio. Menú Tu búsqueda incluye caracteres no compatibles en los dominios de WordPress.com. Se permiten los siguientes caracteres: A–Z, a–z, 0–9. - Comprueba tu conexión a Internet y actualiza la página. - Ir a las estadísticas - Estadísticas de hoy Ha ocurrido un error al actualizar el contenido del aviso + Estadísticas de hoy + Ir a las estadísticas + Comprueba tu conexión a Internet y actualiza la página. Editar - Fallo al moderar los comentarios - Mover a la papelera Marcar como spam + Mover a la papelera + Fallo al moderar los comentarios Rechazar - Ajustes de la galería de mosaico Navega a la pantalla de selección del diseño - Estilo de la galería - Ir a la web + Ajustes de la galería de mosaico Puedes conectar tu cuenta de Facebook en la web de WordPress.com. Cuando lo hayas hecho, vuelve a la aplicación de WordPress para cambiar tus ajustes para compartir. - Icono de la aplicación - Icono de volver - Logotipo de Automattic + Ir a la web + Estilo de la galería WordPress - WooCommerce - Tumblr - Simplenote - Pocket Casts - Jetpack - Day One - Código fuente - Política de privacidad - Términos del servicio + Logotipo de Automattic + Icono de volver + Icono de la aplicación Trabaja desde cualquier lugar - Trabaja con nosotros - Familia Automattic - Legal y otros - Twitter - Instagram - Valóranos - Compartir con amigos + Términos del servicio + Política de privacidad + Código fuente + Day One + Jetpack + Pocket Casts + Simplenote + Tumblr + WooCommerce Puedes editar este bloque usando la versión web del editor. - Abrir los ajustes de seguridad de Jetpack + Compartir con amigos + Valóranos + Instagram + Twitter + Legal y otros + Familia Automattic + Trabaja con nosotros Nota: Debes permitir el acceso desde WordPress.com para editar este bloque en el editor móvil. - Nota: El diseño puede variar entre temas y tamaños de pantalla - Ajustes de la dirección - AÑADIR MEDIOS + Abrir los ajustes de seguridad de Jetpack Estamos teniendo problemas en este momento para cargar los datos de tu sitio. - Algunos datos no se han cargado - El escritorio no está actualizado. Por favor, comprueba tu conexión y luego pulsa para refrescar. - No se ha podido actualizar el escritorio. + AÑADIR MEDIOS + Ajustes de la dirección + Nota: El diseño puede variar entre temas y tamaños de pantalla ¡Vídeo no subido! Para subir vídeos de más de 5 minutos es necesario un plan de pago. - Agradecimientos + No se ha podido actualizar el escritorio. + El escritorio no está actualizado. Por favor, comprueba tu conexión y luego pulsa para refrescar. + Algunos datos no se han cargado Aviso de privacidad de California - Versión %1$s - Agradecimientos - Legal y otros - Sobre %1$s - Blog - Lo básico - Seleccionado: Por defecto - Más opciones de soporte - Obtener soporte - Tamaño de la fuente + Agradecimientos Toca dos veces para seleccionar un tamaño de fuente - Toca dos veces para seleccionar el tamaño de fuente por defecto - Contactar con el soporte - %1$s (%2$s) - Seguir la conversación - Sé el primero en comentar - Ver todos los comentarios + Tamaño de la fuente + Obtener soporte + Más opciones de soporte + Seleccionado: Por defecto + Lo básico + Blog + Sobre %1$s + Legal y otros + Agradecimientos + Versión %1$s Ha habido un error al obtener los datos de la entrada - Ha habido un error al obtener los comentarios + Ver todos los comentarios + Sé el primero en comentar + Seguir la conversación + %1$s (%2$s) + Contactar con el soporte + Toca dos veces para seleccionar el tamaño de fuente por defecto Ajustes para seguir la conversación - Desde el portapapeles + Ha habido un error al obtener los comentarios + Ir a los borradores + Ir a las entradas programadas + Acerca de WordPress Imagen destacada Copiar la URL desde el portapapeles, %s - Acerca de WordPress - Ir a las entradas programadas - Ir a los borradores - Crear una entrada - ¡Publicar regularmente ayuda a crear tu audiencia! - Crear tu próxima entrada - Cambiado a modo visual - Cambiado a modo HTML - Enlace copiado al portapapeles - Autor + Desde el portapapeles Copiar el enlace + Autor + Enlace copiado al portapapeles + Cambiado a modo HTML + Cambiado a modo visual + Crear tu próxima entrada + ¡Publicar regularmente ayuda a crear tu audiencia! + Crear una entrada Añadir un dominio personalizado hace que sea más fácil para tus visitantes encontrar tu sitio Añade tu dominio Las entradas aparecen en la página de tu blog en orden cronológicamente inverso. ¡Es el momento de compartir tus ideas con el mundo! @@ -558,68 +558,68 @@ Language: es <span style=\"color:#008000;\">Gratis el primer año </span><span style=\"color:#50575e;\"><s>%s /año</s></span> Tus dominios redirigirán tu sitio a %s Crear un enlace - Tu nuevo dominio <b>%s</b> está siendo configurando. Tu dominio puede tardar hasta 30 minutos en empezar a funcionar. ¡Felicidades por tu compra! - Seleccionar el dominio - Dominios - Fija - Fijar la entrada en la portada - Marcar como fija - Dejar de seguir la conversación - Activar los avisos de la aplicación + Tu nuevo dominio <b>%s</b> está siendo configurando. Tu dominio puede tardar hasta 30 minutos en empezar a funcionar. Estás siguiendo esta conversación. Recibirás avisos por correo electrónico cuando se publiquen nuevos comentarios. - Gestionar las opciones para seguir la conversación, ventana emergente - No se han podido desactivar los avisos de la aplicación + Activar los avisos de la aplicación + Dejar de seguir la conversación + Marcar como fija + Fijar la entrada en la portada + Fija + Dominios + Seleccionar el dominio No se han podido activar los avisos de la aplicación - Desactivados los avisos de la aplicación - Activados los avisos de la aplicación - Cancelada la suscripción a esta conversación + No se han podido desactivar los avisos de la aplicación + Gestionar las opciones para seguir la conversación, ventana emergente Siguiendo esta conversación\n¿Activar los avisos de la aplicación? + Cancelada la suscripción a esta conversación + Activados los avisos de la aplicación + Desactivados los avisos de la aplicación + Con tu plan, tienes incluido el registro de dominio gratis durante un año Buscar un dominio Los dominios comprados en este sitio redirigirán a los visitantes a <b>%s</b> - Con tu plan, tienes incluido el registro de dominio gratis durante un año - Reclama tu dominio gratuito - Gestionar los dominios Añadir un dominio + Gestionar los dominios + Reclama tu dominio gratuito <span style=\"color:#d63638;\">Caduca el %s</span> - Caduca el %s - Dominios de tu sitio - Dirección principal del sitio Cambiar la dirección del sitio + Dirección principal del sitio + Dominios de tu sitio + Caduca el %s Tu dirección gratuita de WordPress.com es - <span style=\"color:#B26200;\">%1$s el primer año </span><span style=\"color:#50575e;\"><s>%2$s /año</s></span> %s<span style=\"color:#50575e;\"> /año</span> - ¿Quieres descartarlos? - Hay cambios sin guardar - El comentario no puede estar vacío - Correo electrónico del usuario no válido - Dirección web no válida - El nombre de usuario no puede estar vacío - Dirección de correo electrónico - Dirección web - Comentario - Nombre + <span style=\"color:#B26200;\">%1$s el primer año </span><span style=\"color:#50575e;\"><s>%2$s /año</s></span> Hecho + Nombre + Comentario + Dirección web + Dirección de correo electrónico + El nombre de usuario no puede estar vacío + Dirección web no válida + Correo electrónico del usuario no válido + El comentario no puede estar vacío + Hay cambios sin guardar + ¿Quieres descartarlos? Pronto llegarán las vistas previas de los bloques incrustados Resumen semanal - Opciones de incrustación Doble toque para ver las opciones de incrustación. + Opciones de incrustación ¡Sitio creado! Completa otra tarea. - <a href=\"\">A %1$s blogueros</a> les gusta. - <a href=\"\">A 1 bloguero</a> le gusta. - <a href=\"\">A ti y a %1$s blogueros</a> os gusta. <a href=\"\">A ti y a 1 bloguero</a> os gusta. + <a href=\"\">A ti y a %1$s blogueros</a> os gusta. + <a href=\"\">A 1 bloguero</a> le gusta. + <a href=\"\">A %1$s blogueros</a> les gusta. <a href=\"\">A ti</a> te gusta. - Altura de la línea + Error desconocido al recuperar la plantilla recomendada de la aplicación Obtén tu dominio + Altura de la línea %s - Error desconocido al recuperar la plantilla recomendada de la aplicación - Respuesta recibida no válida + Dominios + Enlaces rápidos + Comparte WordPress con un amigo No se ha recibido ninguna respuesta + Respuesta recibida no válida Aplicaciones Automattic - Aplicaciones para cualquier pantalla - Comparte WordPress con un amigo - Enlaces rápidos - Dominios Repaso semanal: %s Hora del aviso Recibirás recordatorios para bloquear <b>todos los días</b> a las <b>%s</b>. @@ -635,86 +635,86 @@ Language: es Los cambios en la imagen destacada no se verán afectados por los botones de deshacer/rehacer. Aplica el ajuste Puedes reorganizar los bloques tocando un bloque y luego tocando las flechas arriba y abajo que aparecen en la parte inferior izquierda del bloque para moverlo encima o debajo de otros bloques. - Bienvenido al mundo de los bloques Para eliminar un bloque, selecciona el bloque y haz clic en los tres puntos de la parte inferior derecha del bloque para ver los ajustes. A partir de ahí, elige la opción para eliminar el bloque. - Algunos bloques tienen ajustes adicionales. Toca el icono de los ajustes en la parte inferior derecha del bloque para ver más opciones. + Bienvenido al mundo de los bloques Bloque %s, disponible nuevamente - Edición de texto enriquecido + Algunos bloques tienen ajustes adicionales. Toca el icono de los ajustes en la parte inferior derecha del bloque para ver más opciones. Una vez que te hayas familiarizado con los nombres de los diferentes bloques, puedes añadir un bloque escribiendo una barra inclinada seguida del nombre del bloque, por ejemplo, «/imagen» o «/encabezado». + Edición de texto enriquecido Haz que tu contenido destaque añadiendo imágenes, gifs, vídeos y medios incrustados a tus páginas. - ¡Pruébalo añadiendo unos cuantos bloques a tu entrada o página! Medio incrustado + ¡Pruébalo añadiendo unos cuantos bloques a tu entrada o página! Cada bloque tiene sus propios ajustes. Para encontrarlos, toca en un bloque. Sus ajustes aparecerán en la barra de herramientas de la parte inferior de la pantalla. - Crear diseños Los bloques son piezas de contenido que puedes insertar, reorganizar y dar estilo sin necesidad de saber programar. Los bloques son una forma fácil y moderna para que crees bonitos diseños. + Crear diseños Los bloques te permiten centrarte en la escritura de tu contenido, sabiendo que todas las herramientas de formato que necesitas están ahí para ayudarte a transmitir tu mensaje. Organiza tu contenido en columnas, añade botones de llamada a la acción y superpón imágenes con texto. - Añade un nuevo bloque en cualquier momento tocando el icono «+» en la barra de herramientas en la parte inferior izquierda. %1$s de %2$s completado - Aprende lo básico con un rápido recorrido. + Añade un nuevo bloque en cualquier momento tocando el icono «+» en la barra de herramientas en la parte inferior izquierda. Ha fallado la moderación de uno o más comentarios + Aprende lo básico con un rápido recorrido. Crear un sitio - Ten tu sitio activo y funcionando en solo unos rápidos pasos - Crea tu web WordPress - No se han podido activar las estadísticas del sitio - Activar las estadísticas del sitio Activa las estadísticas del sitio para ver información detallada sobre el tráfico, los «Me gusta», los comentarios y los suscriptores. - ¿Buscas las estadísticas? + Activar las estadísticas del sitio + No se han podido activar las estadísticas del sitio + Crea tu web WordPress + Ten tu sitio activo y funcionando en solo unos rápidos pasos ¿Qué es un bloque? + ¿Buscas las estadísticas? Estamos trabajando duro para añadir compatibilidad para vistas previas %s. Mientras tanto, puedes previsualizar el contenido incrustado en la entrada. Estamos trabajando duro para añadir compatibilidad para vistas previas %s. Mientras tanto, puedes previsualizar el contenido incrustado en la página. - No se ha podido incrustar el medio - Prueba otro término de búsqueda No se han encontrado bloques + Prueba otro término de búsqueda + No se ha podido incrustar el medio Todavía no están disponibles las vistas previas de %s Pronto llegarán las vistas previas del bloque incrustado %s - Toca dos veces para previsualizar la entrada. - Toca dos veces para previsualizar la página. Mostrado en la pestaña del navegador de tu visitante y en otros sitios online. + Toca dos veces para previsualizar la página. + Toca dos veces para previsualizar la entrada. Muéstrame el camino - ¿Quieres una pequeña ayuda para gestionar este sitio con la aplicación? - Crear un nuevo sitio - Puedes cambiar los sitios en cualquier momento. - Elige un sitio para abrir Lo sentimos, en este momento Jetpack Scan no es compatible con las instalaciones multisitio de WordPress. + Elige un sitio para abrir + Puedes cambiar los sitios en cualquier momento. + Crear un nuevo sitio + ¿Quieres una pequeña ayuda para gestionar este sitio con la aplicación? Los multisitios de WordPress no son compatibles URL no válida. Por favor, introduce una URL válida. - Leyenda incrustada. %s - Leyenda incrustada. Vacía - visita nuestra página de documentación Jetpack Backup para instalaciones multisitio proporciona copias de seguridad descargables, no restauraciones con un solo clic. Para más información, %1$s. + visita nuestra página de documentación + Leyenda incrustada. Vacía + Leyenda incrustada. %s Publicar regularmente puede ayudar a que tus lectores permanezcan implicados, y a atraer nuevos visitantes a tu sitio. Consejo Puedes actualizar esto en cualquier momento Selecciona los días en los que quieres bloguear Puedes actualizar esto en cualquier momento desde Mi sitio > Ajustes > Recordatorios de blogueo. No tienes configurado ningún recordatorio. - Recibirás recordatorios para bloguear %1$s a la semana el %2$s a las %3$s. ¡Recordatorios eliminados! ¡Todo configurado! + Recibirás recordatorios para bloguear %1$s a la semana el %2$s a las %3$s. Actualizar Nada configurado %s a la semana Configurar recordatorios - Configura recordatorios de blogueo los días que quieras publicar. Tu entrada se está publicando … mientras tanto puedes configurar recordatorios de blogueo los días que quiera publicar. + Configura recordatorios de blogueo los días que quieras publicar. Configura tus recordatorios de blogueo Este es tu recordatorio para crear algo hoy Es hora de bloguear en %s WordPress para iOS aún no es compatible con editar bloques reutilizables WordPress para Android aún no es compatible con editar bloques reutilizables Alternativamente, puedes separar y editar estos bloques por separado tocando en «Convertir en bloques normales». - Hecho Avísame + Hecho <a href=\"%1$s\">Introduce las credenciales de tu servidor</a> para activar las restauraciones del sitio con un clic de las copias de seguridad. - Establecer como imagen destacada - Eliminar como imagen destacada Crear una categoría Soporte de WordPress para Android + Eliminar como imagen destacada + Establecer como imagen destacada Gestiona las categorías de tu sitio + El contenido de la página de tus últimas entradas se genera automáticamente y no se puede editar. Categorías Recordatorios - El contenido de la página de tus últimas entradas se genera automáticamente y no se puede editar. Ajustes del borde No mostrar de nuevo Ver el almacenamiento @@ -737,8 +737,8 @@ Language: es Toca dos veces para abrir la hoja de acción para añadir imagen o vídeo La unidad actual es %s Entrada cruzada - %s convertido a bloque normal Ajustes de columnas + %s convertido a bloque normal Añadir enlace a %s Añadir texto del enlace Añadir una imagen o vídeo @@ -758,8 +758,8 @@ Language: es Mover la imagen hacia delante Mover la imagen hacia atrás Ajustes de anchura - «rel» del enlace Ajustes de columna + «rel» del enlace (Sin título) Sitio Información de hoja inferior del perfil de usuario @@ -769,18 +769,18 @@ Language: es Icono social %s Mención NUEVO - Previsualizar la entrada Previsualizar la página + Previsualizar la entrada Reintentar GIF Uno Vista previa no disponible Color del texto Relleno - Cuatro Destacado - URL personalizada + Cuatro Crear una incrustación + URL personalizada Columna %d Describe brevemente el enlace para ayudar a los usuarios de lectores de pantalla Añadir bloques @@ -790,10 +790,10 @@ Language: es Transformar bloque… Fallo al insertar los medios. Fallo al insertar el archivo de audio. - Describe el propósito de la imagen. Déjalo vacío si la imagen es puramente decorativa. %1$s transformado a %2$s Error al cargar los datos de me gusta. %s %d me gusta + Describe el propósito de la imagen. Déjalo vacío si la imagen es puramente decorativa. 1 me gusta Sugerencia: Usar botón de icono @@ -801,13 +801,13 @@ Language: es Botón de búsqueda. El texto actual del botón es Bloques de búsqueda Etiqueta del bloque de búsqueda. El texto actual es - Exterior - No se ha establecido ningún marcador de posición personalizado Dentro + No se ha establecido ningún marcador de posición personalizado Ocultar el encabezado de búsqueda Doble toque para editar el texto del marcador de posición Doble toque para editar el texto de la etiqueta Doble toque para editar el texto del botón + Exterior doble toque para cambiar la unidad El texto de marcador de posición actual es Vaciar la búsqueda @@ -819,24 +819,24 @@ Language: es No hay ninguna red disponible. No hay ningún comentario sin responder Sin responder - AÑADIR ENLACE Ajustes de búsqueda - Direcciones IP permitidas siempre + AÑADIR ENLACE Comentarios no permitidos + Direcciones IP permitidas siempre Añadir el texto del botón Seguir temas - Una nueva forma de crear y publicar contenidos atrayentes en tu sitio. - Descartar Descargar + Descartar + Una nueva forma de crear y publicar contenidos atrayentes en tu sitio. Amenazas corregidas correctamente. Por favor, confirma que quieres corregir todas las %s amenazas activas. La exploración ha encontrado %1$s amenazas potenciales con %2$s. Por favor, revísalas a continuación y lleva a cabo alguna acción o toca el botón de corregir todo. Estamos %3$s si nos necesitas. Trabajamos duro para corregir estas amenazas en segundo plano. Mientras tanto puedes seguir usando tu sitio como siempre, puedes volver a comprobar el progreso en cualquier momento. Editar el punto focal - Toque doble para abrir la hoja del fondo para editar, reemplazar o vaciar la imagen - Toque doble para abrir la hoja de acción para editar, reemplazar o vaciar la imagen example.com Teclea un nombre para tu sitio + Toque doble para abrir la hoja del fondo para editar, reemplazar o vaciar la imagen + Toque doble para abrir la hoja de acción para editar, reemplazar o vaciar la imagen <b>Se han completado todas las tareas</b><br/>Has llegado a más gente. ¡Buen trabajo! <b>Se han completado todas las tareas</b><br/>Has personalizado tu sitio. ¡Bien hecho! Ocultar por ahora @@ -857,18 +857,18 @@ Language: es Enlace de invitación Se ha encontrado una amenaza Se han encontrado amenazas + <b>Exploración finalizada</b><br>No se han encontrado amenazas potenciales <b>Exploración finalizada</b><br>%s amenazas potenciales encontradas <b>Exploración finalizada</b><br>Una amenaza potencial encontrada - <b>Exploración finalizada</b><br>No se han encontrado amenazas potenciales - Corrigiendo la amenaza Desactivar - Desanclar + Corrigiendo la amenaza Revisa tus páginas y haz cambios, o añade o elimina páginas. - Ve tu sitio + Desanclar Descubre y sigue sitios que te inspiren. - Compartir socialmente Comparte automáticamente las nuevas entradas en tus medios sociales. Dale un nombre a tu sitio que refleje su personalidad y temática. + Compartir socialmente + Ve tu sitio Revisa las estadísticas de tu sitio Trataremos de crear un archivo de copia de seguridad descargable. No hemos podido encontrar el estado para decir cuánto tardará tu copia de seguridad descargable. @@ -881,33 +881,33 @@ Language: es Vaya, no hemos podido encontrar el estado de tu restauración No hemos podido restaura tu sitio Confirmar - ¿Estás seguro de querer revertir tu sitio al %1$s a las %2$s?\n Todo lo que hayas cambiado desde entonces se perderá. No hemos podido crear tu copia de seguridad (SQL) (excluye temas, plugins y subidas) + ¿Estás seguro de querer revertir tu sitio al %1$s a las %2$s?\n Todo lo que hayas cambiado desde entonces se perderá. Directorio wp-content Raíz de WordPress - Elementos incluidos en esta descarga Subiendo… + Elementos incluidos en esta descarga Reemplazar archivo Reemplazar audio Problema al abrir el audio - ABRIR Ninguna aplicación puede gestionar esta solicitud. Icono de candado Fallo al insertar el archivo de audio. Por favor, toca para ver las opciones. Toca dos veces para seleccionar un archivo de audio + ABRIR Toca dos veces para escuchar el archivo de audio Elegir audio Reproductor de audio - archivo de audio Leyenda del audio. %s Leyenda del audio. Vacía AÑADIR AUDIO Accede o regístrate con WordPress.com - Usasr este audio Elige un audio del dispositivo Opcional: Introduce un mensaje personalizado que enviar con tu invitación. + Usasr este audio + archivo de audio Aprende más sobre los perfiles Corregido Encontrado @@ -918,19 +918,19 @@ Language: es Bienvenido a la herramienta de exploración de Jetpack, estamos echándole un primer vistazo a tu web en estos momentos, te mostraremos los resultados enseguida. Trabajamos duro para corregir estas amenazas en segundo plano. Mientras tanto puedes seguir usando tu sitio como siempre, puedes volver a comprobar el progreso en cualquier momento. Te enviaremos un aviso si se encuentra una amenaza. Mientras tanto, no dudes en seguir usando tu sitio con normalidad, puedes comprobar el progreso en cualquier momento. - Corrigiendo amenazas Jetpack Scan no ha podido realizar un análisis de tu sitio. Comprueba si tu sitio está caído. Si no, vuelve a intentarlo. Si tu sitio está caído o si Jetpack Scan sigue teniendo problemas, ponte en contacto con nuestro equipo de soporte. + Corrigiendo amenazas Algo ha salido mal Haciendo copia de seguridad del sitio - Haciendo copia de seguridad del sitio desde %1$s %2$s Creando una copia de seguridad descargable + Haciendo copia de seguridad del sitio desde %1$s %2$s La copia de seguridad de tu sitio se ha realizado correctamente + Elegir audio La copia de seguridad de tu sitio se ha realizado correctamente\nHecha copia de seguridad desde %1$s %2$s La copia de seguridad de tu sitio se está realizando\nHaciendo copia de seguridad desde %1$s %2$s - Elegir audio - Hay otra restauración en curso. Icono de error Botón Listo + Hay otra restauración en curso. No se ha podido restaurar Botón Visitar sitio Botón Listo @@ -959,11 +959,11 @@ Language: es Tableta Dispositivos móviles No mostrar de nuevo - Anclar Selecciona %1$s Páginas %2$s para ver tu lista de páginas. Cambia, añade o elimina páginas en tu sitio. Revisar las páginas del sitio Selecciona %1$s Página de inicio %2$s para editar tu página de inicio. + Anclar Marcar como no leída Marcar como leída No se han podido subir los elementos multimedia.\n%1$s @@ -972,8 +972,8 @@ Language: es Marcar entrada como no leída Marcar entrada como leída Se ha producido un error al comprobar el estado de la reparación. Ponte en contacto con el servicio de soporte. - La amenaza se ha corregido correctamente. Se ha producido un error al corregir las amenazas. Ponte en contacto con el servicio de soporte. + La amenaza se ha corregido correctamente. Por favor, confirma que quieres corregir una amenaza activa. Corregir todas las amenazas No se ha podido ignorar la amenaza. Ponte en contacto con el servicio de soporte. @@ -981,7 +981,6 @@ Language: es No deberías ignorar un problema de seguridad a menos que estés absolutamente seguro de que no es dañino. Si eliges ignorar esta amenaza, seguirá en tu sitio <b>%s</b>. No se ha podido corregir la amenaza. Ponte en contacto con el servicio de soporte. Amenaza ignorada - Amenaza corregida el %s Corrigiendo la amenaza Se ha ignorado No se encontró ningún elemento @@ -994,25 +993,26 @@ Language: es Prueba a ajustar el rango de fechas No se han encontrado copias de seguridad coincidentes Tu primera copia de seguridad estará disponible aquí en 24 horas y recibirás una notificación una vez que se haya completado + Amenaza corregida el %s Tu primera copia de seguridad estará lista pronto Ha ocurrido un problema al gestionar la petición. Por favor, inténtalo de nuevo más tarde. Mover al final Cambiar la posición del bloque Subir Icono - También hemos enviado un enlace a tu archivo. Botón de compartir enlace - Botón de descarga - Icono de copia de seguridad descargable lista + También hemos enviado un enlace a tu archivo. Compartir enlace Descargar + Botón de descarga + Icono de copia de seguridad descargable lista Hemos creado una copia de seguridad de tu sitio desde %1$s %2$s. Tu copia de seguridad ya está disponible para descargarla Tu copia de seguridad - No hace falta que esperes. Te avisaremos cuando la copia de seguridad esté lista Icono de copia de seguridad descargable en curso Estamos creando una copia de seguridad descargable de tu sitio desde %1$s %2$s. Se está creando una copia de seguridad descargable de tu sitio + No hace falta que esperes. Te avisaremos cuando la copia de seguridad esté lista Descargar copia de seguridad Hay otra descarga en curso. Ha ocurrido un problema al gestionar la petición. Por favor, inténtalo de nuevo más tarde. @@ -1023,66 +1023,66 @@ Language: es %1$s · entrada cruzada usuario - No coincide con %s. - Ha ocurrido un problema al cargar las sugerencias. - No hay sugerencias %s disponibles. - Escribe algo para filtrar la lista de sugerencias. - Consigue un presupuesto gratuito Ignorar amenaza Corregir amenaza Jetpack Scan solucionará la amenaza. Jetpack Scan editará el archivo o el directorio afectados. Jetpack Scan se actualizará a una versión más reciente (%s). Jetpack Scan borrará el archivo o el directorio afectados. + Consigue un presupuesto gratuito + No coincide con %s. + Ha ocurrido un problema al cargar las sugerencias. + No hay sugerencias %s disponibles. + Escribe algo para filtrar la lista de sugerencias. Jetpack Scan reemplazará el archivo o el directorio afectados. Jetpack Scan no puede solucionar automáticamente esta amenaza.\n Te sugerimos que soluciones esta amenaza manualmente: asegúrate de que WordPress, tu tema y todos los plugins están actualizados y elimina el código, tema o plugin que esté causando problemas en tu sitio web. \n \n\n Si necesitas más ayuda para resolver esta amenaza, te recomendamos <b>Codeable</b>, una plataforma de profesionales de confianza, altamente cualificados, expertos en WordPress.\n Han hecho una selección de expertos en seguridad para ayudarnos con estos proyectos. Los precios oscilan entre 70–120 USD/hora y puedes obtener un presupuesto gratuito sin compromiso. Solucionando la amenaza + ¿Cuál fue el problema? + Información técnica ¿Cómo lo solucionó Jetpack? ¿Cómo vamos a repararlo? Amenaza detectada en el archivo: - Información técnica - ¿Cuál fue el problema? Detalles de la amenaza + Amenaza encontrada %s Se ha encontrado una vulnerabilidad en un tema Se ha encontrado una vulnerabilidad en un plugin - Amenaza encontrada %s Se ha encontrado una vulnerabilidad en WordPress Varias vulnerabilidades - Tema vulnerable: %1$s (versión %2$s) - Plugin vulnerable: %1$s (versión %2$s) %s: patrón de código malicioso Amenazas de base de datos %s + Tema vulnerable: %1$s (versión %2$s) + Plugin vulnerable: %1$s (versión %2$s) %s: archivo principal infectado Se ha encontrado una amenaza + este sitio Corregir todo en unos segundos hace %s minuto(s) hace %s hora(s) - este sitio La última exploración de Jetpack se ejecutó %1$s y no encontró ningún riesgo. %2$s + Copias de seguridad Puede que tu sitio web esté desprotegido No te preocupes Analizar de nuevo Analizar ahora Icono de estado del análisis - Copias de seguridad Filtro de tipo de actividad (%s tipos seleccionados) - %1$s (mostrando %2$s elementos) Filtro de tipo de actividad No se han registrado actividades en el rango de fechas seleccionado. No hay actividades disponibles Revisa tu conexión a Internet e inténtalo de nuevo. + %1$s (mostrando %2$s elementos) Sin conexión Tipo de actividad (%s) Filtro de rango de fechas Intenta ajustar los filtros de rango de fecha o de tipo de actividad No se han encontrado eventos coincidentes - Base de datos del sitio - (incluye wp-config.php y cualquier archivo que no sea de WordPress) Subidas de medios Plugins de WordPress Temas de WordPress Crea un icono de copia de seguridad descargable + (incluye wp-config.php y cualquier archivo que no sea de WordPress) + Base de datos del sitio Crear un archivo descargable Crear una copia de seguridad descargable Descargar copia de seguridad @@ -1101,31 +1101,31 @@ Language: es Duplicar La historia está siendo guardada, por favor, espera… Nombre del archivo - Ajustes del archivo del bloque - Fallo al subir los archivos.\nPor favor, toca para ver las opciones. - Fallo al guardar los medios.\nPor favor, toca para ver las opciones. - Editar el archivo - Copiar la URL del archivo ELEGIR UN ARCHIVO + Copiar la URL del archivo + Editar el archivo + Fallo al guardar los medios.\nPor favor, toca para ver las opciones. + Fallo al subir los archivos.\nPor favor, toca para ver las opciones. + Ajustes del archivo del bloque Elige un dominio - Ajustes de Jetpack Jetpack + Error al recuperar el estado de suscripción para la entrada + No se ha podido crear la suscripción a los comentarios de esta entrada + No se ha podido anular la suscripción a los comentarios de esta entrada Siguiendo la conversación por correo electrónico Seguir la conversación por correo electrónico - No se ha podido anular la suscripción a los comentarios de esta entrada - No se ha podido crear la suscripción a los comentarios de esta entrada - Error al recuperar el estado de suscripción para la entrada + Ajustes de Jetpack Respuesta recibida no válida No se ha recibido ninguna respuesta Vaciar Aplicar Una o más diapositivas no se han añadido a tu historia porque en este momento las historias no son compatibles con archivos GIF. Por favor, elige una imagen estática o un vídeo de fondo en su lugar. - Los archivos GIF no son compatibles - No hemos podido encontrar en el sitio los medios para esta historia. No se puede editar la historia No ha sido posible subir medios a esta historia. Comprueba tu conexión a Internet e inténtalo de nuevo dentro de un momento. No se puede editar la historia Esta historia se ha editado en un dispositivo diferente y la posibilidad de editar ciertos objetos puede estar limitada. + No hemos podido encontrar en el sitio los medios para esta historia. + Los archivos GIF no son compatibles Edición limitada de la historia Los medios han sido eliminados. Intenta volver a crear tu historia. Fondo @@ -1136,10 +1136,10 @@ Language: es Hecho Siguiente Borrar - Se ha producido un error al elegir el tema. Por favor, revisa tu conexión a Internet e inténtalo de nuevo. Toca en reintentar cuando vuelvas a estar conectado. Los diseños no están disponibles sin conexión + Se ha producido un error al elegir el tema. Continuar con las credenciales de la tienda Encuentra tu correo electrónico conectado Seguir temas @@ -1147,9 +1147,9 @@ Language: es No hay entradas recientes ¡Bienvenido! Explorar - <b>Juan Gómez</b> ha respondido en tu entrada - Hoy has recibido <b>50 me gusta</b> en tu sitio A <b>Madison Ruíz</b> le ha gustado tu entrada + Hoy has recibido <b>50 me gusta</b> en tu sitio + <b>Juan Gómez</b> ha respondido en tu entrada Se ha abierto el menú de bloques desplazable. Selecciona un bloque. Se ha cerrado el menú de bloques desplazable. Elegir @@ -1176,47 +1176,47 @@ Language: es Pamela Nguyen Estoy muy inspirado por el trabajo del fotógrafo Cameron Karsten. Probaré estas técnicas en mi próximo Inspírate - Sigue tus sitios favoritos y descubre nuevos blogs. Observa cómo crece tu audiencia con analíticas avanzadas. - Mira los comentarios y avisos en tiempo real. Con el potente editor puedes publicar sobre la marcha. Bienvenido al maquetador web más popular del mundo. + Mira los comentarios y avisos en tiempo real. + Sigue tus sitios favoritos y descubre nuevos blogs. La carga del medio ha fallado Sitios a seguir Estamos trabajando duro para añadir más bloques con cada versión. «%s» no es totalmente compatible - Botón de ayuda - Editar usando el editor web - Elegir las imágenes - Crear una entrada de historia Son publicados como una nueva entrada de blog en tu sitio para que tu audiencia nunca se pierda nada. - Las entradas de historias no desaparecen + Crear una entrada de historia + Elegir las imágenes + Editar usando el editor web + Botón de ayuda Combina fotos, vídeos y texto para crear entradas de historias atractivas y accesibles que les encantarán a tus visitantes. - Ahora las historias son para todos - Título de la entrada de historia - Cómo crear una entrada de historias - Presentación de las entradas de historias - Página en blanco creada - Página creada + Las entradas de historias no desaparecen %1$s ha denegado el acceso a tus fotos. Para corregirlo, edita tus permisos y activa %2$s y %3$s. - Inserción del medio fallida. - Ha fallado la inserción del medio: %s + Página creada + Página en blanco creada + Presentación de las entradas de historias + Cómo crear una entrada de historias + Título de la entrada de historia + Ahora las historias son para todos Elige desde la biblioteca de medios de WordPress + Ha fallado la inserción del medio: %s + Inserción del medio fallida. Volver + por Primeros pasos Sigue temáticas para descubrir nuevos blogs - por - Este referido no puede ser marcado como spam - Desmarcar como spam - Marcar como spam - Abrir la web - Subiendo medios GIF - Subiendo medios de inventarios Subiendo medios + Subiendo medios de inventarios + Subiendo medios GIF + Abrir la web + Marcar como spam + Desmarcar como spam + Este referido no puede ser marcado como spam Busca o escribe la URL Añadir este enlace de teléfono - Añadir este enlace Añadir este enlace de correo electrónico + Añadir este enlace No hay conexión a Internet.\nNo están disponibles las sugerencias. Negrita Moderno @@ -1233,126 +1233,125 @@ Language: es No se puede mostrar este comentario Navegar por elementos Informar de esta entrada - Bienvenido al Lector. Descubre millones de blogs a tu alcance. - Ha ocurrido un error interno del servidor - Tu acción no está permitida %1$s elementos más + Tu acción no está permitida + Ha ocurrido un error interno del servidor + Bienvenido al Lector. Descubre millones de blogs a tu alcance. Seleccionar un diseño Nota: el diseño de la columna puede variar entre temas y tamaños de pantalla - Crear una entrada o historia - Crear una página Crear una entrada - Puede que te guste + Crear una página + Crear una entrada o historia Ocultar - Leyenda del vídeo. Vacía - Actualiza el título. - Pegar el bloque después - Título de la página. %s - Título de la página. Vacío - Ha ocurrido un error al reproducir tu vídeo - Este dispositivo no es compatible con la API de Camera2 - No se ha podido guardar el vídeo - Error al guardar la imagen + Puede que te guste + Ver el almacenamiento Operación en progreso, inténtalo de nuevo + Error al guardar la imagen + No se ha podido guardar el vídeo + Este dispositivo no es compatible con la API de Camera2 + Ha ocurrido un error al reproducir tu vídeo + Título de la página. Vacío + Título de la página. %s + Pegar el bloque después + Actualiza el título. + Leyenda del vídeo. Vacía No se ha podido encontrar la diapositiva de la historia - Ver el almacenamiento - Tenemos que guardar la historia en tu dispositivo antes de que pueda ser publicada. Revisa tus ajustes de almacenamiento y elimina archivos para ganar espacio. - Insuficiente almacenamiento en el dispositivo - Intenta volver a guardar o borrar las diapositivas y, después, intenta volver a publicar tu historia. - No se han podido guardar %1$d diapositivas - No se ha podido guardar 1 diapositiva - Gestionar - %1$d diapositivas necesitan una acción 1 diapositiva necesita una acción - No se ha podido subir «%1$s» - No se ha podido subir «%1$s» - Publicado «%1$s» + %1$d diapositivas necesitan una acción + Gestionar + No se ha podido guardar 1 diapositiva + No se han podido guardar %1$d diapositivas + Intenta volver a guardar o borrar las diapositivas y, después, intenta volver a publicar tu historia. + Insuficiente almacenamiento en el dispositivo + Tenemos que guardar la historia en tu dispositivo antes de que pueda ser publicada. Revisa tus ajustes de almacenamiento y elimina archivos para ganar espacio. Subiendo «%1$s»… - Quedan %1$d diapositivas - Queda 1 diapositiva - varias historias + Publicado «%1$s» + No se ha podido subir «%1$s» + No se ha podido subir «%1$s» Guardando «%1$s»… - Sin título - Descartar - La entrada de tu historia no se guardará como borrador. - ¿Descartar la entrada de la historia? - Borrar - Esta diapositiva aún no ha sido guardada. Si borras esta diapositiva, perderás cualquier edición que hayas hecho. - Esta diapositiva será eliminada de tu historia. - ¿Borrar la diapositiva de la historia? - Cambiar el color del texto - Cambiar la alineación del texto - con error - seleccionado + varias historias + Queda 1 diapositiva + Quedan %1$d diapositivas sin seleccionar - Diapositiva - Reintentar - Guardado - Cerrar - Compartir con - COMPARTIR - Guardado en fotos - Reintentar - Guardado - Guardando - Flash - Girar - Sonido - Texto - Pegatinas + seleccionado + con error + Cambiar la alineación del texto + Cambiar el color del texto + ¿Borrar la diapositiva de la historia? + Esta diapositiva será eliminada de tu historia. + Esta diapositiva aún no ha sido guardada. Si borras esta diapositiva, perderás cualquier edición que hayas hecho. + Borrar + ¿Descartar la entrada de la historia? + La entrada de tu historia no se guardará como borrador. + Descartar + Sin título + Toca crear %1$s. %2$s Después selecciona <b>Entrada del blog</b> + Pon un título a tu historia + Empieza eligiendo entre una amplia variedad de diseños de página prefabricados. O simplemente empieza con una página en blanco. + Crear una página en blanco + Crear una página + Vista previa + Capturar Flash + Pegatinas + Texto + Sonido Girar la cámara - Capturar - Vista previa - Crear una página - Crear una página en blanco - Empieza eligiendo entre una amplia variedad de diseños de página prefabricados. O simplemente empieza con una página en blanco. - Elegir un diseño - Pon un título a tu historia - Crear una entrada o historia + Girar + Flash + Guardando + Guardado + Reintentar + Guardado en fotos + COMPARTIR + Compartir con + Cerrar + Guardado + Reintentar + Diapositiva Crear una entrada, página o historia - Toca crear %1$s. %2$s Después selecciona <b>Entrada del blog</b> - Elegir el dispositivo + Crear una entrada o historia + Elegir un diseño + Cuota de almacenamiento superada + No se puede subir el archivo.\nSe ha superado la cuota de almacenamiento. + No se ha podido encontrar el salto de página enlazado Entrada de la historia + Elegir el dispositivo Para la edición de los iconos del sitio en sitios WordPress autoalojados se necesita el plugin Jetpack. - No se ha podido encontrar el salto de página enlazado - No se puede subir el archivo.\nSe ha superado la cuota de almacenamiento. - Cuota de almacenamiento superada Añadir un archivo - Reemplazar el vídeo Reemplazar la imagen o vídeo - Convertir en enlace - Elegir un vídeo - Elegir una imagen o vídeo - Elegir una imagen + Reemplazar el vídeo + Si continúas con Google y aún no tienes una cuenta de WordPress.com, crearás una cuenta y aceptas nuestros %1$stérminos del servicio%2$s. + Confirmación del registro Bloque eliminado + Elegir una imagen + Elegir una imagen o vídeo + Elegir un vídeo Introduce la dirección de tu sitio existente - Confirmación del registro - Si continúas con Google y aún no tienes una cuenta de WordPress.com, crearás una cuenta y aceptas nuestros %1$stérminos del servicio%2$s. + Convertir en enlace Si continúas, aceptas nuestros %1$stérminos del servicio%2$s. Usaremos esta dirección de correo electrónico para crear tu nueva cuenta de WordPress.com. Te hemos enviado por correo electrónico un enlace de registro para crear tu nueva cuenta de WordPress.com. Comprueba tu correo electrónico en este dispositivo y toca el enlace en el correo electrónico que has recibido de WordPress.com. Introduce la información de tu cuenta para %1$s. - o - Continuar con Google - Encuentra la dirección de tu sitio - Hecho - ¿No ves el correo electrónico? Comprueba tu carpeta de spam o correo no deseado. Comprueba tu correo electrónico en este dispositivo y toca el enlace en el correo electrónico que has recibido de WordPress.com. + ¿No ves el correo electrónico? Comprueba tu carpeta de spam o correo no deseado. + Hecho + Encuentra la dirección de tu sitio + Continuar con Google + o Te enviaremos por correo electrónico un enlace que te hará acceder automáticamente, sin necesidad de contraseña. - Comprobar el correo electrónico - Primeros pasos - Introduce tu dirección de correo electrónico para acceder o crear una cuenta de WordPress.com. - O escribe tu contraseña - Crear una cuenta - Enviar el enlace por correo electrónico Restablecer tu contraseña + Enviar el enlace por correo electrónico + Crear una cuenta + O escribe tu contraseña + Introduce tu dirección de correo electrónico para acceder o crear una cuenta de WordPress.com. + Primeros pasos + Comprobar el correo electrónico Ha habido un problema al gestionar la solicitud. Por favor, inténtalo de nuevo más tarde. - Comprueba el título de tu sitio Toca <b>%1$s</b> para configurar un nuevo título + Comprueba el título de tu sitio Al enviar esta entrada a la papelera también se descartarán los cambios locales, ¿estás seguro de que quieres continuar? Opciones del bloque %s - Eliminar el bloque Duplicar bloque Copiar bloque Bloque copiado @@ -1361,10 +1360,11 @@ Language: es Bloque cortado Bloque copiado El título del sitio solo puede ser cambiado por un usuario con el perfil de administrador. + Eliminar el bloque El título del sitio se muestra en la barra de título de un navegador web y en la cabecera de la mayoría de los temas. - Tema No se ha podido actualizar el título del sitio. Comprueba tu conexión de red e inténtalo nuevamente. Cambios sin guardar + Tema Abrir el enlace en un navegador Navega a la hoja de contenido anterior Navega para personalizar el degradado @@ -1381,7 +1381,6 @@ Language: es Descartar No establecido Las etiquetas ayudan a los lectores diciéndoles de qué se trata la entrada. - Fecha de publicación Añadir etiquetas Volver Guardar ahora @@ -1393,9 +1392,8 @@ Language: es Cancelar Mover a borrador Las entradas en la papelera no se pueden editar. ¿Deseas cambiar el estado de esta entrada a «borrador» para poder trabajar en ella? + Fecha de publicación ¿Mover entrada a borradores? - Elige tus temáticas - Elige tus temáticas Hecho Selecciona algunos para continuar Publicado @@ -1404,51 +1402,53 @@ Language: es Fecha de publicación Lee el aviso de privacidad de CCPA La Ley de Privacidad del Consumidor de California («CCPA») nos obliga a que proporcionemos información adicional a los residentes de California sobre las categorías de información personal que recopilamos y compartimos, dónde obtenemos esa información personal y cómo y por qué la usamos. + Elige tus temáticas + Elige tus temáticas Aviso de privacidad para usuarios de California Estado y visibilidad Actualizar ahora Abrir el menú de acciones de bloques Mover arriba - Insertar una mención - Toca dos veces para abrir la hoja inferior con las opciones disponibles Toca dos veces pata abrir la hoja de acción con las opciones disponibles - No podemos abrir las páginas en este momento. Por favor, inténtalo de nuevo más tarde - Establecer como página de entradas + Toca dos veces para abrir la hoja inferior con las opciones disponibles + Insertar una mención + La página de inicio seleccionada y la página de entradas no pueden ser la misma. + Blog clásico + Página de inicio estática + Página de entradas + Seleccionar la página Establecer como página de inicio + Establecer como página de entradas + No podemos abrir las páginas en este momento. Por favor, inténtalo de nuevo más tarde %1$s no es una %2$s válida - Seleccionar la página - Página de entradas - Página de inicio estática - Blog clásico - La página de inicio seleccionada y la página de entradas no pueden ser la misma. - Ha fallado la actualización de la página de inicio, comprueba tu conexión a internet - No se pueden guardar los ajustes de la página de inicio antes de que las páginas estén cargadas - No se pueden guardar los ajustes de la página de inicio - Aceptar - Ha fallado la carga de las páginas - Elige entre una página de inicio que muestre tus últimas publicaciones (blog clásico) o una página fija/estática. Ajustes de la página de inicio + Elige entre una página de inicio que muestre tus últimas publicaciones (blog clásico) o una página fija/estática. + Ha fallado la carga de las páginas + Aceptar + No se pueden guardar los ajustes de la página de inicio + No se pueden guardar los ajustes de la página de inicio antes de que las páginas estén cargadas + Ha fallado la actualización de la página de inicio, comprueba tu conexión a internet + Para establecer la página de inicio, activa «Página de inicio estática» en los ajustes del sitio + Para establecer la página de entradas, activa «Página de inicio estática» en los ajustes del sitio + Página de inicio actualizada correctamente + Ha fallado la actualización de la página de inicio + Página de entradas actualizada correctamente Página de inicio Ha fallado la actualización de la página de entradas - Página de entradas actualizada correctamente - Ha fallado la actualización de la página de inicio - Página de inicio actualizada correctamente - Para establecer la página de entradas, activa «Página de inicio estática» en los ajustes del sitio - Para establecer la página de inicio, activa «Página de inicio estática» en los ajustes del sitio Seleccionar un color - Toca dos veces para ir a los ajustes del color Cuando sigas sitios, verás aquí su contenido + Toca dos veces para ir a los ajustes del color Saber más - Qué hay de nuevo en %s Insertar %d recortar Fallo al cargar en el archivo, por favor, inténtalo de nuevo. Vista previa de la miniatura de la imagen - Usar este medio Usar este vídeo Elegir el medio Elegir el vídeo + Usar este medio No se ha podido seleccionar el sitio. Por favor, inténtalo de nuevo. + Qué hay de nuevo en %s Continuar Ha fallado reblog Gestionar los sitios @@ -1469,13 +1469,13 @@ Language: es Mover bloque a la izquierda Toca dos veces para mover el bloque hacia la derecha Toca dos veces para mover el bloque hacia la izquierda - Ajustes del bloque Creando el escritorio Configurar el tema Añadiendo las características del sitio Obteniendo la URL del sitio Tu sitio estará listo en breve ¡Hurra!\nCasi está hecho + Ajustes del bloque Cancelar la subida Ha habido un problema al gestionar la petición Funciona con Tenor @@ -1490,12 +1490,12 @@ Language: es Ha fallado el acceso al contenido de un sitio privado. Algunos medios pueden no estar disponibles Accediendo al contenido de un sitio privado Fallo al recortar y guardar la imagen, por favor, inténtalo de nuevo. - Fallo al cargar la imagen.\nPor favor, toca para volver a intentarlo. Previsualizar la imagen Formato de página desconocido No hemos podido completar esta acción y no se ha enviado esta página a revisión. No hemos podido completar esta acción y no se ha programado esta página. No hemos podido completar esta acción y no se ha publicado esta página privada. + Fallo al cargar la imagen.\nPor favor, toca para volver a intentarlo. No hemos podido completar esta acción y no se ha publicado esta página. No hemos podido enviar esta página a revisión, pero lo intentaremos de nuevo más tarde. No hemos podido programar esta página, pero lo intentaremos de nuevo más tarde. @@ -1510,20 +1510,20 @@ Language: es Programaremos tu página cuando tu dispositivo vuelva a estar online. Enviaremos tu página para revisión cuando tu dispositivo vuelva a estar online. Publicaremos la página cuando tu dispositivo vuelva a estar online. + Has hecho cambios no guardados en esta página Página en espera Subiendo la página El dispositivo está desconectado. La página se ha guardado localmente. - Has hecho cambios no guardados en esta página Tu página se está subiendo - La página ha fallado al subir los medios y ha sido guardada localmente Página guardada en el dispositivo La página se ha guardado online - Selecciona un blog para el atajo a QuickPress - Establecido por el ahorrador de batería Oscuro Claro Apariencia Recientemente has hecho cambios en esta página, pero no los has guardado. Elige una versión para cargar:\n\n + Establecido por el ahorrador de batería + La página ha fallado al subir los medios y ha sido guardada localmente + Selecciona un blog para el atajo a QuickPress Mostrar el contenido de la entrada Mostrar solo el extracto Enlazar a @@ -1538,8 +1538,8 @@ Language: es En la papelera Programada Publicada - La conexión con Facebook no puede encontrar ninguna página. Jetpack Social no puede conectar con perfiles de Facebook, solo con páginas publicadas. No conectado + La conexión con Facebook no puede encontrar ninguna página. Jetpack Social no puede conectar con perfiles de Facebook, solo con páginas publicadas. Me gusta Seguimientos Comentarios @@ -1549,25 +1549,25 @@ Language: es Actividad Entradas y páginas General - Añadir una nueva tarjeta Añadir una nueva tarjeta de estadísticas + Añadir una nueva tarjeta Usa el botón de filtro para encontrar entradas sobre temas específicos Selecciona una etiqueta o sitio, ventana emergente Selecciona un sitio o etiqueta para filtrar entradas Quitar el filtro actual - Gestionar temas y sitios Acceder a WordPress.com - Accede a WordPress.com para ver las últimas entradas de los temas que sigues + Gestionar temas y sitios Accede a WordPress.com para ver las últimas entradas de los sitios que sigues + Accede a WordPress.com para ver las últimas entradas de los temas que sigues Reemplazar el bloque actual Añadir al final Añadir al principio Añadir el bloque antes Añadir el bloque después - Añadir un tema Seguir un sitio - Puedes seguir entradas sobre un tema específico añadiendo un tema Mira las entradas más recientes de los sitios que sigues + Añadir un tema + Puedes seguir entradas sobre un tema específico añadiendo un tema Siguiendo Filtrar Leyenda del vídeo. %s @@ -1579,10 +1579,10 @@ Language: es Has escuchado todas las estadísticas de este período.\n Si vuelves a tocar, se reiniciará desde el principio. No hay estadísticas en este período. Actividad de publicación para %1$s - Los días con visitas %1$s para %2$s son: %2$s %3$s. Toca para más. explora todas las estadísticas para este período muy altas altas + Los días con visitas %1$s para %2$s son: %2$s %3$s. Toca para más. medias bajas   y %1$d %2$s @@ -1611,22 +1611,22 @@ Language: es No hemos podido acceder a tu sitio porque necesita <b>identificación HTTP</b>. Tendrás que contactar con tu alojamiento para solucionarlo. No hemos podido acceder en tu sitio al <b>archivo XMLRCP</b>. Tendrás que contactar con tu alojamiento para solucionarlo. ¡Ya casi estamos! Solo necesitamos verificar tu dirección de correo electrónico conectada a Jetpack <b>%1$s</b> - Accede con las credenciales de tu sitio %1$s - Página del sitio Siguiendo - Me gusta - Descubrir - Guardado - Temas - Sitios - %sE - %sP + Página del sitio + Accede con las credenciales de tu sitio %1$s + No podemos abrir las entradas en este momento. Por favor, inténtalo de nuevo más tarde + %sM %sT + Sitios + Guardado + Descubrir + Me gusta + No podemos cargar los datos para tu sitio en este momento. Por favor, inténtalo de nuevo más tarde %sG - %sM + %sP + %sE + Temas %sK - No podemos abrir las entradas en este momento. Por favor, inténtalo de nuevo más tarde - No podemos cargar los datos para tu sitio en este momento. Por favor, inténtalo de nuevo más tarde Biblioteca de medios de WordPress No compatible Desagrupar @@ -1652,12 +1652,12 @@ Language: es Mover el bloque arriba Mover el bloque hacia abajo, de la fila %1$s a la fila %2$s Mover el bloque abajo - Texto del enlace Enlace insertado Leyenda de la imagen. %s Ocultar el teclado Icono de ayuda Toca dos veces para deshacer el último cambio + Texto del enlace Toca dos veces para alternar los ajustes Toca dos veces para seleccionar una imagen Toca dos veces para seleccionar un vídeo @@ -1674,10 +1674,10 @@ Language: es Texto alternativo AÑADIR UN VÍDEO Añadir la URL - Añadir el texto alternativo AÑADIR UNA IMAGEN O UN VÍDEO AÑADIR UNA IMAGEN AÑADIR EL BLOQUE AQUÍ + Añadir el texto alternativo Toca el botón «Añadir a las entradas guardadas» para guardar una entrada en tu lista. La lista se ha cargado con %1$d elementos. Avisos @@ -1715,11 +1715,11 @@ Language: es Has hecho cambios no guardados en esta entrada La versión desde esta aplicación La versión desde otro dispositivo - Desde esta aplicación\nGuardado en %1$s\n\nDesde otro dispositivo\nGuardado en %2$s\n Recientemente has hecho cambios en esta entrada, pero no los has guardado. Elige una versión para cargar:\n\n ¿Qué versión te gustaría editar? Borrar permanentemente No guardaremos los últimos cambios en tu borrador. + Desde esta aplicación\nGuardado en %1$s\n\nDesde otro dispositivo\nGuardado en %2$s\n No programaremos estos cambios. No enviaremos estos cambios para revisión. No publicaremos estos cambios. @@ -1755,8 +1755,8 @@ Language: es Archivo Descargas de archivos Las estadísticas de descarga de archivos no se registraron antes del 28 de Junio de 2019. - Zona horaria del sitio (UTC -%s) Zona horaria del sitio (UTC +%s) + Zona horaria del sitio (UTC -%s) Zona horaria del sitio (UTC) Escritorio Por defecto @@ -1765,9 +1765,9 @@ Language: es Compartir Volver Avanzar - «%1$s» programado para publicar el «%2$s» en tu aplicación de %3$s\n%4$s Entrada programada de WordPress: «%s» «%s» se publicará en 10 minutos + «%1$s» programado para publicar el «%2$s» en tu aplicación de %3$s\n%4$s «%s» se publicará en 1 hora «%s» ha sido publicado Entrada programada: recordatorio de 10 minutos @@ -1777,9 +1777,9 @@ Language: es Cuando se publique 10 minutos antes 1 hora antes - Desactivado Añadir al calendario Aviso + Desactivado Fecha y hora Por favor, introduce una dirección completa de una web, como example.com. Accede con WordPress.com para conectar con %1$s @@ -1789,15 +1789,15 @@ Language: es Elemento contraído Elemento expandido Contraer - Ampliar Gráfico actualizado. %1$s %2$s del período: %3$s, cambio desde el período anterior - %4$s Cargando los datos de la tarjeta seleccionada Editor - Ampliar + Ampliar Cerrar Verifica tu dirección de correo electrónico - las instrucciones se enviaron a tu correo electrónico Verifica tu dirección de correo electrónico - las instrucciones se enviaron a %s + Ampliar Cancelar Aceptar http(s):// @@ -1830,22 +1830,21 @@ Language: es Histórico Visitas esta semana Añadir widget - Está tardando más tiempo del normal recargar los detalles del plugin. Por favor, compruébalo de nuevo más tarde. Si acabas de registrar un nombre de dominio, por favor, espera hasta que terminemos de configurarlo e inténtalo de nuevo.\n\nEn caso contrario, parece que algo fue mal y la característica del plugin podría no estar disponible para este sitio. + Está tardando más tiempo del normal recargar los detalles del plugin. Por favor, compruébalo de nuevo más tarde. Estado (no disponible) Al registrar este dominio aceptas nuestros %1$stérminos y condiciones%2$s Comprueba tu conexión a la red e inténtalo de nuevo. No se ha podido cargar esta página en este momento. - No se pudieron recuperar los ajustes. Algunas APIs no están disponibles para la cuenta e ID de esta aplicación OAuth. Al configurar Jetpack aceptas nuestros %1$stérminos y condiciones%2$s + No se pudieron recuperar los ajustes. Algunas APIs no están disponibles para la cuenta e ID de esta aplicación OAuth. No hay ninguna conexión. La edición está desactivada. - Para volver a conectar la aplicación con tu sitio alojado, introduce aquí la nueva contraseña del sitio. Contraseña actualizada Actualizar contraseña + Para volver a conectar la aplicación con tu sitio alojado, introduce aquí la nueva contraseña del sitio. Registrando el nombre de dominio… Selecciona la provincia Selecciona el país - Registrar un dominio Código postal Provincia Ciudad @@ -1854,6 +1853,7 @@ Language: es País Código del país Teléfono + Registrar un dominio Organización (opcional) Para tu comodidad, hemos precompletado tu información de contacto\n de WordPress.com. Por favor, comprueba que es la información correcta que quieres usar para este dominio. Información de contacto del dominio @@ -1872,34 +1872,34 @@ Language: es Fallo al insertar los medios.\nPor favor, toca para volver a intentarlo. Tu borrador se está subiendo Subiendo borrador - Borradores Ocurrió un error mientras se restauraba la entrada - Retroceder a: %s - Solo ves las estadísticas más relevantes. Añade y organiza tus detalles abajo. + Borradores Social Estadísticas anuales del sitio - Seguidores totales + Registrar dominio + Solo ves las estadísticas más relevantes. Añade y organiza tus detalles abajo. + Retroceder a: %s No se pudieron cargar las sugerencias de dominios Teclea una palabra clave para más ideas No se han encontrado sugerencias - Registrar dominio - Quitar de los detalles + Seguidores totales Mover abajo Mover arriba - Ajustes de los parámetros de las estadísticas - La entrada se está moviendo a borradores - La entrada se está restaurando - Entrada restaurada + Cambios locales La entrada se está enviando a la papelera + Entrada restaurada + La entrada se está restaurando + La entrada se está moviendo a borradores + Quitar de los detalles + Ajustes de los parámetros de las estadísticas Al enviar esta entrada a la papelera también se descartarán los cambios sin guardar, ¿estás seguro de querer continuar? - Cambios locales - Mover a borradores - Cambiar a la vista de lista - Cambiar a la vista de tarjetas - No tienes ninguna entrada en la papelera - No tienes ninguna entrada en borrador - No tienes ninguna entrada programada Aún no has publicado ninguna entrada + No tienes ninguna entrada programada + No tienes ninguna entrada en borrador + No tienes ninguna entrada en la papelera + Cambiar a la vista de tarjetas + Cambiar a la vista de lista + Mover a borradores Por favor, accede con tu nombre de usuario y contraseña. Por favor, accede usando tu nombre de usuario de WordPress.com en vez de tu dirección de correo electrónico. Promedio de palabras/entrada @@ -1910,17 +1910,15 @@ Language: es Total de comentarios Entradas Año - Este año El sitio de esta dirección no es un sitio WordPress. Para que nos podamos conectar el sitio debe usar WordPress. + Este año Fallo al comprobar los créditos de dominio disponibles Comprobando créditos de dominio Registrar dominio Para instalar plugins necesitas tener un dominio personalizado asociado a tu sitio. Instalar plugin - Podrás personalizar la apariencia de tu sitio más tarde - Publicar el: %s - Programada para el: %s Publicado el: %s + Publicar el: %s Programado para el: %s Últimas semanas Vistas medias por dia @@ -1928,18 +1926,20 @@ Language: es Período Meses y años Cargar más + Podrás personalizar la apariencia de tu sitio más tarde + Programada para el: %s Hoy Mejor hora Mejor día Estadísticas del: No, gracias - Más tarde Valorar ahora + Más tarde ¡Qué gusto verte de nuevo! Si estás trabajando con la aplicación nos encantaría que nos puntuases en la Google Play Store. - Entrada devuelta a borrador - Actividad de publicación El sitio no se ha cargado todavía + Entrada devuelta a borrador Más entradas + Actividad de publicación Menos entradas Puedes perder lo que llevas hecho. ¿Estás seguro de que quieres salir? Ver los planes @@ -1948,33 +1948,33 @@ Language: es No podemos cargar los planes en este momento. Por favor, inténtalo de nuevo. No se pueden cargar los planes No hay conexión - Cambiar al editor de bloques Hubo un problema al cargar tus datos, recarga la página e inténtalo de nuevo. Datos no cargados Edita las nuevas entradas y páginas con el editor de bloques Usar editor de bloques + Cambiar al editor de bloques salir + Siguientes pasos + Tus visitantes verán tu icono en su navegador. Añade un icono personalizado para conseguir un aspecto profesional y refinado. Haz crecer tu audiencia Personaliza tu sitio - Siguientes pasos Elige un icono del sitio único - Tus visitantes verán tu icono en su navegador. Añade un icono personalizado para conseguir un aspecto profesional y refinado. - Selecciona las %1$s estadísticas %2$s para ver cómo está rindiendo tu sitio. Toca en %1$s Icono de tu sitio %2$s para subir uno nuevo Guarda en borrador y publica una entrada. + Selecciona las %1$s estadísticas %2$s para ver cómo está rindiendo tu sitio. Activar compartir entradas Comparte automáticamente las nuevas entradas en tus cuentas de medios sociales. Revisa las estadísticas de tu sitio - Mantente al día sobre el rendimiento de tu sitio. - Eliminar los siguientes pasos ocultará todas las visitas guiadas de este sitio. Esta acción es irreversible. Quitar los siguientes pasos Quitar esto + Eliminar los siguientes pasos ocultará todas las visitas guiadas de este sitio. Esta acción es irreversible. + Mantente al día sobre el rendimiento de tu sitio. Saltar tarea Recordatorio Elige el siguiente periodo Elige el periodo anterior - %1$s de visitas Hora más popular + %1$s de visitas %1$s (%2$s) +%1$s (%2$s) Mostrando la vista previa @@ -1983,19 +1983,19 @@ Language: es Cancelar el asistente de creación de sitios Estamos creando tu nuevo sitio Hubo un problema - Crear sitio Crear sitio Aquí es donde la gente te encontrará en Internet. + Crear sitio No hay direcciones disponibles que coincidan con tu búsqueda Error durante la comunicación con el servidor. Inténtalo de nuevo Hubo un problema Hubo un problema + Conflicto de versiones ¡Se ha creado tu sitio! %1$d de %2$d Crear sitio Sugerencias actualizadas No se ha podido seleccionar el sitio auto-hospedado que acabas de añadir - Conflicto de versiones Activa los informes de errores automáticos para ayudarnos a mejorar el rendimiento de la app. Informes de errores Deshacer @@ -2003,24 +2003,27 @@ Language: es Versión local descartada Actualizando contenido Descartar web + Resolver conflicto de sincronización + Este contenido tiene dos versiones en conflicto. Selecciona qué versión quieres descartar.\n Descartar local Local\nGuardado el %1$s\n\nWeb\nGuardado el %2$s\n - Este contenido tiene dos versiones en conflicto. Selecciona qué versión quieres descartar.\n - Resolver conflicto de sincronización No hay datos en este periodo Eliminar la ubicación de los medios No podemos abrir las estadísticas en este momento. Por favor, inténtalo de nuevo más tarde - Ningún medio coincide con tu búsqueda - ¡Busca para encontrar GIF para añadir a tu biblioteca de medios! - Vistas Autor Autores + LinkedIn + Google+ + Tumblr + Twitter + Facebook + Título + Ruta + Vistas Vistas Buscar término Buscar términos Vistas - Título - Vídeos Vistas País Paises @@ -2031,45 +2034,42 @@ Language: es Referente Referentes Entradas y páginas - Ruta - LinkedIn - Google+ - Tumblr - Twitter - Facebook Ver más Compartir entrada Crear entrada Han pasado %1$s desde que se publicó %2$s. Así es como ha funcionado la entrada hasta ahora: - Han pasado %1$s desde que se publicó %2$s. Pon la bola a rodar y aumenta las vistas de las entradas compartiendo tu entrada: + Ningún medio coincide con tu búsqueda + ¡Busca para encontrar GIF para añadir a tu biblioteca de medios! + Vídeos Etiquetas y categorías + Han pasado %1$s desde que se publicó %2$s. Pon la bola a rodar y aumenta las vistas de las entradas compartiendo tu entrada: Histórico %1$s - %2$s + %1$s | %2$s + Autor + Autores + Correo electrónico + WordPress.com + Título + Título Seguidores + Seguidor + Total %1$s seguidores: %2$s Servicio - %1$s | %2$s Vistas Título Vistas - Título Comentarios - Título - Autor Entradas y páginas - Autores Desde - Seguidor - Total %1$s seguidores: %2$s - Correo electrónico - WordPress.com Gestionar datos Aún no se han añadido impresiones Aún no hay datos Menú de depuración Cambiando contraseña… - Tu contraseña debe tener al menos seis caracteres de longitud. Para hacerla más fuerte, usa letras mayúsculas y minúsculas, números y símbolos como ! \" ? $ % ^ & ). Contraseña cambiada con éxito Cambiar contraseña + Tu contraseña debe tener al menos seis caracteres de longitud. Para hacerla más fuerte, usa letras mayúsculas y minúsculas, números y símbolos como ! \" ? $ % ^ & ). Nombre (sin título) Vista previa HTML @@ -2078,7 +2078,6 @@ Language: es Anterior Siguiente %1$s utilizado - Por favor, introduce un sitio WordPress WordPress.com o autoalojado conectado a Jetpack Cargando revisión Revisión cargada Cargar @@ -2087,23 +2086,24 @@ Language: es Aún no hay histórico Cuando haces cambios a tu entrada podrás ver aquí el histórico Cuando haces cambios a tu página podrás ver aquí el histórico + Por favor, introduce un sitio WordPress WordPress.com o autoalojado conectado a Jetpack Avatar del usuario Tamaño completo Grande Mediano Miniatura Historia - La página seleccionada no está disponible Pendiente de revisión + La página seleccionada no está disponible No tienes ninguna página en la papelera No tienes ninguna página programada - No tienes ninguna página en borrador Todavía no has publicado ninguna página Buscar páginas Ninguna página coincide con tu búsqueda Borrar permanentemente Mover a la papelera Mover a borradores + No tienes ninguna página en borrador Hacer superior Ver En la papelera @@ -2131,11 +2131,11 @@ Language: es Pon tu sitio en marcha. ¿A que se siente uno bien terminando una lista? Ver tu sitio - Previsualiza tu sitio para ver lo que verán tus visitantes. Comparte tu sitio + Conecta a tus cuentas de medios sociales - tu sitio compartirá automáticamente las nuevas entradas. Toca en %1$s Compartir %2$s para continuar Toca en %1$s Conexiones %2$s para añadir tus cuentas de medios sociales - Conecta a tus cuentas de medios sociales - tu sitio compartirá automáticamente las nuevas entradas. + Previsualiza tu sitio para ver lo que verán tus visitantes. Publica una entrada Toca en %1$s Crear entrada %2$s para crear una nueva entrada No, gracias @@ -2143,26 +2143,26 @@ Language: es Ir Cancelar Ahora no - Más No tienes sitios + Más Temas no seguidos Añade aquí temas para descubrir entradas sobre tus temáticas favoritas - Accede a la cuenta de WordPress.com que usaste para conectar Jetpack. Jetpack FAQ de Jetpack + Accede a la cuenta de WordPress.com que usaste para conectar Jetpack. Para usar las estadísticas en tu sitio WordPress necesitas instalar el plugin Jetpack. No hay temas que coincidan con tu búsqueda ¿Que te gustaría encontrar? No hay etiquetas que coincidan con tu búsqueda No tienes ninguna etiqueta - Añade aquí las etiquetas que uses frecuentemente para poder seleccionarlas rápidamente al etiquetar tus entradas Crea una etiqueta No hay medios que coincidan con tu búsqueda ¿Salir de WordPress? + Añade aquí las etiquetas que uses frecuentemente para poder seleccionarlas rápidamente al etiquetar tus entradas Tienes cambios en entradas que no se han subido a tu sitio. Salir ahora borrará esos cambios de tu dispositivo. ¿Quieres salir de todos modos? - No hay lectores aún - No hay seguidores por correo electrónico aún No hay seguidores aún + No hay seguidores por correo electrónico aún + No hay lectores aún No hay usuarios aún Las entradas que te gusten aparecerán aquí Nada que te gustó aún @@ -2184,198 +2184,198 @@ Language: es imagen destacada Descartar foto de perfil - Dato transitorio + WordPress + Correo electrónico de contacto Correo electrónico Por favor, introduce tu dirección de correo electrónico + No establecido Para continuar, por favor, introduce tu dirección de correo electrónico y nombre + Dato transitorio Nuevo mensaje de «Ayuda y soporte» - WordPress - No establecido - Correo electrónico de contacto Restauración en progreso Restaurando a %1$s %2$s Actualmente restaurando tu sitio + Botón de acción del registro de actividad Tu sitio ha sido restaurado satisfactoriamente - Tu sitio ha sido restaurado correctamente\nRestaurado a %1$s %2$s Tu sitio está siendo restaurado\nRestaurando a %1$s %2$s - Botón de acción del registro de actividad + Tu sitio ha sido restaurado correctamente\nRestaurado a %1$s %2$s Gestionado automáticamente Guarda esta entrada y vuelve cuando quieras para leerla. Solo estará disponible en este dispositivo — las entradas guardadas no se sincronizan con otros dispositivos. - Guardar entradas para más tarde - No ha sido posible realizar la búsqueda No se han encontrado resultados - Lee la entrada de origen + No ha sido posible realizar la búsqueda + Guardar entradas para más tarde Sitios + Lee la entrada de origen Enlace mágico enviado Verificación del código Credenciales de acceso Enlace mágico enviado Acceso por enlace mágico - Acceso mediante la dirección del sitio Acceso mediante dirección de correo electrónico + Acceso mediante la dirección del sitio Toca %s para guardar una entrada en tu lista. - ¡Aún no hay entradas guardadas! Entrada guardada Ver todas Borrada de las entradas guardadas - Añadir a las entradas guardadas Entradas guardadas Borrado - Cambiar icono del sitio + ¡Aún no hay entradas guardadas! + Añadir a las entradas guardadas Cancelar - Eliminar Cambiar - No tienes permiso para editar el icono del sitio. - No tienes permiso para añadir un icono al sitio. + Cambiar icono del sitio + Activar ¿Cómo te gustaría editar el icono? - ¿Te gustaría añadir un icono de sitio? + Eliminar Icono del sitio este sitio - Activar - ¿Activar avisos para %1$s%2$s%3$s? - Activar los avisos del sitio - Desactivar los avisos del sitio - Icono de Jetpack - Evento + No tienes permiso para añadir un icono al sitio. + No tienes permiso para editar el icono del sitio. + ¿Te gustaría añadir un icono de sitio? Icono de actividad Registro de actividad - Lee la política de privacidad - Usamos otras herramientas de seguimiento, incluidas algunas de terceros. Lee acerca de estas y cómo controlarlas. - Política de terceros - Esta información nos ayuda a mejorar nuestros productos, hacer que el marketing sea más relevante, personalizar tu experiencia en WordPress.com y más, tal como se detalla en nuestra política de privacidad. - Política de privacidad - Comparte información con nuestra herramienta de análisis acerca del uso que haces de los servicios mientras estás conectado a tu cuenta de WordPress.com. + Recopilar información Política de cookies + ¿Activar avisos para %1$s%2$s%3$s? + Evento + Icono de Jetpack + Política de privacidad Ajustes de privacidad - Recopilar información + Lee la política de privacidad + Política de terceros + Desactivar los avisos del sitio + Activar los avisos del sitio + Usamos otras herramientas de seguimiento, incluidas algunas de terceros. Lee acerca de estas y cómo controlarlas. + Comparte información con nuestra herramienta de análisis acerca del uso que haces de los servicios mientras estás conectado a tu cuenta de WordPress.com. + Esta información nos ayuda a mejorar nuestros productos, hacer que el marketing sea más relevante, personalizar tu experiencia en WordPress.com y más, tal como se detalla en nuestra política de privacidad. Entrada enviada Una característica del plugin requiere que el sitio esté en buen estado. Una característica del plugin necesita que la suscripción del dominio principal esté asociada con este usuario. - Una característica del plugin necesita privilegios de administrador. El plugin no puede instalarse en sitios VIP. El plugin no se puede instalar debido a las limitaciones de espacio del disco. - Una característica del plugin requiere una dirección de correo electrónico verificada. - Una característica del plugin requiere que el sitio sea público. Una característica del plugin requiere un plan business. Una característica del plugin requiere un dominio personalizado. + Una característica del plugin necesita privilegios de administrador. + Una característica del plugin requiere una dirección de correo electrónico verificada. + Una característica del plugin requiere que el sitio sea público. Estamos haciendo la configuración final, está casi listo… Instalando plugin… Instalar Instalar el primer plugin en tu sitio puede llevar hasta 1 minuto. Durante este tiempo no podrás realizar cambios en tu sitio. Instalar plugin - Avisos Enviarme nuevos comentarios por correo electrónico - Semanalmente Instantáneamente - Diariamente Entradas nuevas - Recibe avisos de las nuevas entradas de este sitio Enviarme nuevas entradas por correo electrónico + Semanalmente + Diariamente + Avisos + Recibe avisos de las nuevas entradas de este sitio Todos mis sitios seguidos Sitios seguidos - Dispositivo de lectura personal con avisos Gente mirando gráficos y tablas - %1$s en %2$s ¿Seguro que quieres eliminar definitivamente esta publicación? + Dispositivo de lectura personal con avisos + %1$s en %2$s Importante General Utilizar esta foto %1$d de %2$d Fotografías facilitadas por %s Busca para encontrar fotografías gratuitas para añadir a tu biblioteca de medios - Búsqueda en la biblioteca de fotos gratuitas Selecciona de la biblioteca gratuita de fotos No se puede guardar un borrador vacío - %1$s de ilimitado Vista previa %d Añadir %d + %1$s de ilimitado + Búsqueda en la biblioteca de fotos gratuitas Crear etiqueta + Imagen de perfil de %s + audio navegar hacia arriba - Avisos - Abrir enlace externo - mostrar más + abrir cámara foto + elige desde el dispositivo + elige desde medios de WordPress + reproduce + papelera + mostrar más borrar - Reproducir vídeo - reproducir vídeo destacado logo del plugin banner del plugin - elige desde medios de WordPress - abrir cámara - elige desde el dispositivo información del perfil - reproduce previsualizar imagen - vista previa - audio - reproducir vídeo - papelera reintentar vista previa de medios, nombre de archivo %s eliminar %s - Imagen de perfil de %s - marca de verificación Registrarse con Google… + vista previa + marca de verificación + Abrir enlace externo + Avisos + Reproducir vídeo + reproducir vídeo destacado + reproducir vídeo Se ha producido un error en la conexión a Jetpack: %s Ya estás conectado a Jetpack + %s TB Modo visual Modo HTML Vista previa Guardar como borrador - %s TB + %1$s de %2$s + %s B %s GB - %s MB %s kB - %s B - %1$s de %2$s - Si necesitas más espacio, considera actualizar tu plan de WordPress. - Espacio utilizado - Medios + %s MB + Comentario aprobado + Comentario borrado Comentario marcado como no spam Comentario marcado como spam - Comentario borrado Comentario restaurado Comentario enviado a la papelera - El comentario no ha gustado - El comentario ha gustado Comentario sin aprobar - Comentario aprobado + Cuenta nueva Detalle de notificación %s - Editar foto Elige el sitio - Cuenta nueva - Conectado como + Espacio utilizado + Si necesitas más espacio, considera actualizar tu plan de WordPress. + Medios + El comentario no ha gustado + El comentario ha gustado + Editar foto + Ajustes de avisos Detalle de la persona + Conectado como Detalles del archivo Botones de compartir - Avisos Lector Yo + Avisos Mi sitio - Ajustes de avisos Tu avatar se ha subido y estará disponible en breve. - Parece que has desactivado los permisos necesarios para esta característica.<br/><br/>Para cambiarlo, edita tus permisos y asegúrate de que <strong>%s</strong> está activado. Permisos Destacados + Versión %s + Parece que has desactivado los permisos necesarios para esta característica.<br/><br/>Para cambiarlo, edita tus permisos y asegúrate de que <strong>%s</strong> está activado. No puedes acceder a tus ajustes para compartir porque tu módulo de compartir de Jetpack está desactivado. Módulo para compartir desactivado. - Versión %s El sonido escogido tiene una ruta incorrecta. Por favor, elige uno distinto. QP %s quedan %1$d páginas / entradas Queda 1 página quedan %1$d páginas quedan %1$d entradas - %1$d páginas / entradas y 1 archivo restantes %1$d entradas y 1 archivo restantes + %1$d páginas / entradas y 1 archivo restantes %1$d páginas y 1 archivo restantes 1 entrada y 1 archivo restantes 1 página y 1 archivo restantes - %1$d páginas / entradas y %2$d de %3$d archivos restantes %1$d entradas y %2$d de %3$d archivos restantes + %1$d páginas / entradas y %2$d de %3$d archivos restantes quedan %1$d páginas y %2$d de %3$d archivos - queda 1 entrada y %1$d de %2$d archivos queda 1 página y %1$d de %2$d archivos + queda 1 entrada y %1$d de %2$d archivos %1$d entradas / páginas sin subir %1$d páginas sin subir 1 página sin subir @@ -2400,26 +2400,26 @@ Language: es Cambiar nombre de usuario Teclea para obtener más sugerencias Tu nombre de usuario actual es %1$s%2$s%3$s. Con pocas excepciones, otros solo verán tu nombre a mostrar, %4$s%5$s%6$s. - No se ha sugerido ningún nombre de usuario desde %1$s%2$s%3$s. Por favor, introduce más letras o números para obtener sugerencias. - Ocurrió un error al recuperar sugerencias de nombres de usuario. - ¿Descartas cambiar de nombre de usuario? Descartar Guardar Añadir avatar + No se ha sugerido ningún nombre de usuario desde %1$s%2$s%3$s. Por favor, introduce más letras o números para obtener sugerencias. + Ocurrió un error al recuperar sugerencias de nombres de usuario. + ¿Descartas cambiar de nombre de usuario? El correo electrónico ya existe en WordPress.com.\nAcceder. Actualizando cuenta… Enviando correo - Reintentar - Cerrar - Hubo algún problema al enviar el correo. Puedes reintentarlo ahora o cerrar e intentarlo más tarde. Nombre de usuario - Siempre puedes acceder con un enlace como el que acabas de usar, pero también puedes configurar una contraseña si lo prefieres. - Contraseña (opcional) Nombre a mostrar Reintentar Revertir + Reintentar + Cerrar + Contraseña (opcional) Hubo algún problema al actualizar tu cuenta. Puedes reintentarlo o revertir tus cambios para continuar. Hubo algún problema al subir tu avatar. + Hubo algún problema al enviar el correo. Puedes reintentarlo ahora o cerrar e intentarlo más tarde. + Siempre puedes acceder con un enlace como el que acabas de usar, pero también puedes configurar una contraseña si lo prefieres. Necesita actualizarse Buscar plugins Nuevo @@ -2462,11 +2462,11 @@ Language: es por %s Cambiar foto No es posible cargar plugins - Páginas Gestiona las etiquetas de tu sitio Guardando Borrando ¿Borrar permanentemente la etiqueta \'%s\'? + Páginas Ya existe una etiqueta con este nombre Añadir nueva etiqueta Descripción @@ -2553,8 +2553,8 @@ Language: es «Desconectar de WordPress.com» Puedes marcar una dirección IP (o series de direcciones) como «Siempre permitida», evitando que sea bloqueada por Jetpack. Se aceptan IPv4 y IPv6. Para especificar un rango, introduce un valor inferior y un valor superior separados por un guión. Ejemplo: 12.12.12.1–12.12.12.100 Requiere la identificación en dos pasos - Relacionar cuentas usando el correo electrónico Permitir el acceso con WordPress.com + Relacionar cuentas usando el correo electrónico Acceso con WordPress.com Bloquea intentos de acceso maliciosos Protección contra ataques de fuerza bruta @@ -2572,21 +2572,21 @@ Language: es Eliminando ¿Borrar este vídeo? ¿Eliminar esta imagen? - Detalles del documento Detalles del audio + Detalles del documento Detalles del vídeo - Detalles de la imagen Vista previa - Fecha de actualización + Detalles de la imagen Duración + Fecha de actualización Dimensiones de vídeo Sin imagen - Tipo de archivo Nombre del archivo + Tipo de archivo URL Texto alternativo - Conectar un sitio Luz parpadeante + Conectar un sitio Vibración del dispositivo Elige sonido Vistas y sonidos @@ -2601,8 +2601,8 @@ Language: es Activar los avisos Desactivar los avisos Desactivado - Activado Tamaño máximo de vídeo + Activado Tamaño máximo de imagen Hubo un error al subir los medios a esta entrada: %s. Hubo un error al subir esta entrada: %s. @@ -2625,8 +2625,8 @@ Language: es Entrada programada Reintentar Entrada a la espera - Subiendo «%s» Se ha perdido la conexión al servidor + Subiendo «%s» Mis sitios Mi sitio No se pudo detectar una aplicación cliente de correo electrónico @@ -2642,22 +2642,22 @@ Language: es Introduce la dirección del sitio WordPress con el que te gustaría conectar. Ya estás conectado a WordPress.com Seguir - Conectar otro sitio Introduce tu contraseña de WordPress.com + Conectar otro sitio Solicitando el correo electrónico de acceso Parece que esta contraseña es incorrecta. Por favor, vuelve a comprobar tu información e inténtalo de nuevo. Solicitando un código de verificación por SMS. Envíame un mensaje con un código en su lugar ¡Casi lo tenemos! Por favor, introduce un código de verificación desde tu aplicación Authenticator. - Abrir correo electrónico Siguiente Accede a WordPress.com usando una dirección de correo electrónico para gestionar todos tus sitios WordPress. + Abrir correo electrónico La optimización de imagen reduce las imágenes para que suban más rápido.\n\nPuedes cambiar esto en cualquier momento en los ajustes del sitio. ¿Activar optimización de la imagen? - Detener - Activar Foto de perfil Respuesta inesperada del servidor + Detener + Activar No se puede detener la subida porque ya ha finalizado Título Rehacer @@ -2669,24 +2669,24 @@ Language: es Ocurrió un error al arrastrar texto No está permitido arrastrar imágenes en el modo HTML Comparte tu historia aquí… - Privada Borrador Pendiente de revisión + Privada Publicar Ahora Solo los que tengan esta contraseña pueden ver esta entrada Los extractos son resúmenes opcionales del contenido hechos a mano. El slug es la versión amigable de la URL del título de la entrada. - Formato de entrada Etiquetas Slug Extracto - No definido + Formato de entrada Más opciones Categorías y etiquetas + No definido Todos - Nivel superior Categoría superior (opcional): + Nivel superior No tienes ningún audio No tienes ningún documento No tienes ningún vídeo @@ -2799,11 +2799,11 @@ Language: es Media Baja Subido - Fallo al subir Se ha eliminado Eliminando Subiendo En cola + Fallo al subir Calidad de la imagen Todos los archivos de medios se han cancelado debido a un error desconocido. Por favor, vuelve a intentar cargarlos Formato de entrada desconocido @@ -2819,8 +2819,8 @@ Language: es Optimiza las imágenes Error de los archivos multimedia Hubo un error al cargar el archivo multimedia - Reintentar Confirmar + Reintentar No se pudo conectar. Se ha recibido un error 403 cuando se intenta acceder a \n tu endpoint del XMLRPC de sitio. La aplicación lo necesita para comunicarse con tu sitio. Ponte en contacto con tu proveedor para solucionar este problema. No se pudo conectar. Tu alojamiento está bloqueando las peticiones POST, y la aplicación las necesita \n para comunicarse con tu sitio. Ponte en contacto con tu alojamiento para solucionar este problema. Buscar en los sitios seguidos @@ -2850,8 +2850,8 @@ Language: es Procesando… ¡Acción realizada! Comentario marcado como me gusta - Cerrar sesión Iniciar sesión en WordPress.com + Cerrar sesión Más en WordPress.com Más de %s Abrir ajustes del dispositivo @@ -2863,47 +2863,47 @@ Language: es ¡Comentario aprobado! Me gusta ahora - Espectador Seguidor + Espectador Sin conexión, no se pudo guardar tu perfil - Derecha - Izquierda Ninguna + Izquierda + Derecha Seleccionado %1$d No se pudieron recuperar los usuarios del sitio - Correo electrónico del seguidor Seguidor + Correo electrónico del seguidor Recuperando usuarios… - Espectadores Suscriptores por correo electrónico + Espectadores Seguidores Equipo Invita como máximo a 10 personas con sus correos electrónicos o nombre de usuarios de WordPress.com. A aquellos que necesiten un nombre de usuario se le enviará instrucciones sobre cómo hacerlo. Si eliminas a este espectador, no podrá visitar tu sitio\n\n¿Todavía quieres eliminar a este espectador? Si lo eliminas, este seguidor dejará de recibir informaciones de tu sitio, a no ser que vuelta a seguirte. \n\n¿Todavía quieres eliminar a este seguidor? Desde %1$s - No se pudo quitar el espectador No se pudo quitar al seguidor + No se pudo quitar el espectador No se pudieron recuperar los correos electrónicos de los seguidores del sitio No se pudieron recuperar los seguidores del sitio Algunas subidas de medios han fallado. Puedes cambiar al modo HTML \ncuando esto pasa. ¿Borramos todas las subidas fallidas y seguimos? - Miniatura de la imagen Editor visual + Miniatura de la imagen + Cambios guardados Ancho - Enlazado a - Texto alternativo Leyenda - Cambios guardados + Texto alternativo + Enlazado a ¿Descartar cambios sin guardar? ¿Parar la subida? Hubo un error al insertar el archivo multimedia Ahora mismo estás subiendo medios. Por favor, espera hasta que termine. No se pueden insertar medios directamente en el modo HTML. Por favor, cambia al modo visual. Subiendo galería… - ¡Toca para probar de nuevo! Invitación enviada con éxito - %1$s: %2$s ¡Se han enviado las invitaciones pero ha habido errores! + ¡Toca para probar de nuevo! + %1$s: %2$s ¡Hubo un error al tratar de enviar la invitación! No se pudo enviar: Hay nombres de usuario o correos electrónicos no válidos. No se pudo enviar: Un nombre de usuario o correo electrónico no es válido @@ -2911,8 +2911,8 @@ Language: es Mensaje personalizado Invitar Nombres de usuarios o correos electrónicos - Invitar a gente Externo + Invitar a gente Borrar historial de búsqueda ¿Borrar historial de búsqueda? No se han encontrado resultados con %s para tu idioma @@ -2920,33 +2920,33 @@ Language: es Entrada relacionada Los enlaces están desactivados en la pantalla de vista previa Enviar - %1$s eliminado correctamente Si eliminas %1$s, ese usuario ya no será capaz de acceder a este sitio, pero cualquier contenido que fuera creado por %1$s permanecerá en el sitio.\n\n¿Aún te gustaría eliminar este usuario? + %1$s eliminado correctamente Eliminar %1$s - Perfil - Gente Los sitios de esta lista no han publicado nada últimamente. + Gente + Perfil No se ha podido eliminar el usuario No se ha podido actualizar el rol del usuario No se pudieron recuperar los espectadores del sitio Error al subir tu Gravatar - Error al recargar tu Gravatar Error al localizar la imagen recortada + Error al recargar tu Gravatar Error al recortar la imagen Comprobando correo electrónico Actualmente no disponible. Por favor, introduce tu contraseña Accediendo Cuando comentes se hará público Captura o elige imagen - Planes Plan + Planes Tus entradas, páginas y ajustes te serán enviadas por correo electrónico a %s. Exportar tu contenido - ¡Correo electrónico de exportación enviado! Exportando contenido… - Comprobando compras + ¡Correo electrónico de exportación enviado! Mostrar compras Tienes mejoras premium en tu sitio. Por favor, cancela tus mejoras antes de eliminar tu sitio. + Comprobando compras Mejoras premium Algo fue mal. No se pudo realizar la compra. Borrando sitio… @@ -2962,8 +2962,8 @@ Language: es Si quieres un sitio, pero no quieres ninguna de las entradas y las páginas que tiene ahora, nuestro equipo de soporte puede borrar sus mensajes, páginas, archivos multimedia y tus comentarios.\n\nEsto mantendrá su sitio y la URL activos, pero tendrás un nuevo comienzo en la creación de contenidos. Sólo tienes que contactar con nosotros para limpiar tu contenido actual.. Déjanos ayudarte Comienza tu sitio encima - Comenzar de nuevo Ajustes de la app + Comenzar de nuevo Eliminar subidas fallidas Avanzado No hay comentarios en la papelera @@ -2971,34 +2971,34 @@ Language: es No hay comentarios aprobados Saltar No se ha podido conectar. Los métodos XML-RPC necesarios faltan en el servidor. + Estado Centrado Vídeo - Estado - Estándar - Cita - Enlace - Imagen - Galería Chat + Galería + Imagen + Enlace + Cita + Estándar + Información sobre cursos y eventos de WordPress.com (online y presenciales). Audio Minientrada - Información sobre cursos y eventos de WordPress.com (online y presenciales). Oportunidades para participar en investigaciones y encuestas en WordPress. Consejos para sacar el máximo partido a WordPress.com Comunidad - Investigación - Sugerencias Respuestas a mis comentarios - Menciones del nombre de usuario + Sugerencias + Investigación Logros del sitio + Menciones del nombre de usuario Seguidores del sitio «Me gusta» en mis entradas «Me gusta» en mis comentarios Comentarios en mi sitio %d elementos 1 elemento - Todos los usuarios Comentarios de usuarios conocidos + Todos los usuarios Sin comentarios %d comentarios por página 1 comentario por página @@ -3008,11 +3008,11 @@ Language: es Aprobar automáticamente los comentarios de todo el mundo. Aprobar automáticamente si el usuario tiene un comentario previamente aprobado Se requiere aprobación manual de los comentarios de todos. - %d días 1 día - Dirección web + %d días Sitio principal Haz click en el enlace de verificación del correo electrónica enviado a %1$s para confirmar tu nueva dirección + Dirección web Actualmente estás subiendo archivos multimedia. Por favor, espera hasta que se complete. No se pudieron actualizar los comentarios ahora mismo - se muestran comentarios antiguos Establece la imagen destacada @@ -3021,13 +3021,13 @@ Language: es ¿Eliminar de forma permanente estos comentarios? ¿Eliminar de forma permanente este comentario? Eliminar - Restaurar Comentario eliminado + Restaurar No hay comentarios spam - Todos No se pudo cargar la página - Off + Todos Idioma del interface + Off Sobre la app No se pudieron guardar los ajustes de la cuenta No se pudieron recuperar los ajustes de tu cuenta @@ -3035,9 +3035,9 @@ Language: es No se pudo reconocer el código del idioma Permite los comentarios anidados. Anidar hasta + Eliminar Desactivado Buscar - Eliminar Tamaño original Tu sitio es visible únicamente por ti y por lo usuarios que apruebes Tu sitio es visible para todos pero pide a los motores de búsqueda no ser indexado @@ -3046,9 +3046,9 @@ Language: es Sobre mí El nombre público mostrará por defecto el nombre de usuario si no está establecido Nombre que se mostrará públicamente - Apellidos - Nombre Mi perfil + Nombre + Apellidos Imagen de vista previa de entradas relacionadas No pudo guardar la información del sitio No pudo recuperar la información del sitio @@ -3119,22 +3119,22 @@ Language: es Formato por defecto Categoría por defecto Dirección - Descripción corta Título del sitio + Descripción corta Por defecto para nuevas entradas - Escribiendo Cuenta + Escribiendo General Nuevos primero - Antiguos primero - Cerrar después de Comentarios - Entradas relacionadas Privacidad + Antiguos primero Discusión + Entradas relacionadas + Cerrar después de No tienes permisos para subir multimedia al sitio - Desconocido Nunca + Desconocido Esta entrada ya no existe No estás autorizado a ver esta entrada No se pudo recuperar esta entrada @@ -3146,22 +3146,22 @@ Language: es Se ha producido un error. No se ha podido activar el tema de %1$s Gracias por elegir %1$s - GESTIONAR SITIO - HECHO - Ayuda - Detalles - Vista Probar y personalizar + Vista + Detalles + Ayuda + HECHO + GESTIONAR SITIO Activar - Activo - Ayuda - Detalles - Personalizar Tema actual - Página actualizada - Entrada actualizada - Página publicada + Personalizar + Detalles + Ayuda + Activo Entrada publicada + Página publicada + Entrada actualizada + Página actualizada Lo sentimos, no se han encontrados temas. Cargar más entradas Ningún sitio coincide con «%s» @@ -3193,280 +3193,280 @@ Language: es Tipos de avisos No se han podido cargar los ajustes de avisos Me gusta al comentario - Avisos de la aplicación Correo electrónico + Avisos de la aplicación Pestaña de avisos Siempre mandamos correos electrónicos importantes relativos a tu cuenta, pero también obtendrás extras útiles. Sumario de la última entrada Sin conexión Entrada enviada a la papelera - Papelera Estadísticas + Papelera Vista previa Ver - Publicar Editar + Publicar No tienes autorización para acceder a este sitio No se pudo encontrar este sitio Deshacer La solicitud ha expirado. Accede a WordPress.com para volver a intentarlo. - Ignorar El mejor día + Ignorar Estadísticas de hoy Entradas, vistas y visitantes de todos los tiempos Detalles Salir de WordPress.com - Acceder a WordPress.com Iniciar/Cerrar sesión - Ajustes de la cuenta + Acceder a WordPress.com «%s» no se ha ocultado porque es el sitio actual + Ajustes de la cuenta Crear sitio en WordPress.com Añadir sitio autoalojado - Añadir sitio nuevo Mostrar/Ocultar sitios - Elegir sitio - Ver sitio - Ver Administrador + Añadir sitio nuevo Cambiar sitio - Ajustes del sitio - Entradas + Ver Administrador + Ver sitio + Elegir sitio Publicar Aspecto + Ajustes del sitio + Entradas Configuración Toca para mostrarlos - Anular todas las selecciones - Seleccionar todo - Ocultar Mostrar - Accede de nuevo para continuar. + Ocultar + Seleccionar todo + Anular todas las selecciones + Idioma Código de verificación no válido Código de verificación - Idioma - No se pudieron recuperar las entradas + Accede de nuevo para continuar. No se pudo abrir la notificación Términos de búsqueda desconocidos - Términos de búsqueda Autores + Términos de búsqueda Recuperando páginas… Recuperando entradas… Recuperando medios… - Los registros de la aplicación han sido copiados al portapapeles - Este sitio está vacío + No se pudieron recuperar las entradas Nuevas entradas - Ha ocurrido un error al copiar el texto en el portapapeles Subiendo entrada - %1$d años - Un año + Este sitio está vacío + Ha ocurrido un error al copiar el texto en el portapapeles + Los registros de la aplicación han sido copiados al portapapeles + Obteniendo temas… %1$d meses + Un año + %1$d años Un mes - %1$d días - Un día - %1$d horas - hace una hora %1$d minutos + hace una hora + %1$d horas + Un día + %1$d días hace un minuto hace unos segundos - Seguidores - Vídeos Entradas y páginas + Vídeos + Seguidores Países Me gusta - Visitantes - Vistas Años - Obteniendo temas… + Vistas + Visitantes Detalles %d seleccionados - Explora nuestras Preguntas frecuentes. Aún no hay comentarios - No hay entradas con esta temática - Me gusta Ver artículo original + Me gusta Los comentarios están cerrados %1$d de %2$d No se puede publicar una entrada vacía. No tienes permiso para ver o editar entradas. No tienes permiso para ver o editar páginas. - Más Hace más de 1 mes - Hace más de 1 semana + Más Hace más de 2 días - Ayuda y soporte + Hace más de 1 semana Me gustó Comentario El comentario se ha enviado a la papelera. Responder a %s + Explora nuestras Preguntas frecuentes. Aún no se han publicado entradas. ¿Por qué no crear una? Cerrando sesión… + No hay entradas con esta temática + Ayuda y soporte No es posible realizar esta acción No es posible bloquear este sitio Las entradas de este sitio no volverán a mostrarse Bloquear este sitio - Programar Actualizar - Sin sitios recomendados - No se puede dejar de seguir este sitio - No se puede seguir este sitio + Programar + Sitios que sigues Ya estás siguiendo este sitio - No se puede mostrar este sitio Sitio seguido + No se puede mostrar este sitio + No se puede seguir este sitio + No se puede dejar de seguir este sitio + Sin sitios recomendados + Sitio del lector Introduce una URL o tema para seguir - Sitios que sigues Temas seguidos - Sitio del lector - SI normalmente se conecta sin problemas a este sitio sin problemas, este error puede significar que alguien están intentando suplantar el sitio, por lo que no deberías continuar. ¿Quieres, de todas formas, confiar en el certificado? - Certificado SSL no válido Ayuda - El nombre de usuario o contraseña que has introducido son incorrectos - Introduce una dirección de correo electrónico válida - Tu dirección de correo electrónico no es válida - Error al descargar la imagen - No se pudo cargar el comentario + Certificado SSL no válido + SI normalmente se conecta sin problemas a este sitio sin problemas, este error puede significar que alguien están intentando suplantar el sitio, por lo que no deberías continuar. ¿Quieres, de todas formas, confiar en el certificado? + Ocurrió un error al obtener los temas. + Las entradas no pueden ser actualizadas en este momento + Las páginas no pueden ser actualizadas en este momento. + No es spam + No se pudo añadir la categoría + Ocurrió un error Ocurrió un error al editar el comentario Ocurrió un error al moderar el comentario - Ocurrió un error + Tu dirección de correo electrónico no es válida + El campo nombre de categoría es necesario + No se pudo cargar el comentario + Error al descargar la imagen + Se necesita una tarjeta SD montada para subir medios + El elemento multimedia no ha podido ser recuperado No se pudieron actualizar los comentarios - Las páginas no pueden ser actualizadas en este momento. - Las entradas no pueden ser actualizadas en este momento Ocurrió un error al eliminar la entrada - Sin avisos - Se necesita una tarjeta SD montada para subir medios - El campo nombre de categoría es necesario Categoría añadida correctamente - No se pudo añadir la categoría - No es spam - Ocurrió un error al obtener los temas. - Ha ocurrido un error al acceder a este blog - El elemento multimedia no ha podido ser recuperado + Introduce una dirección de correo electrónico válida + El nombre de usuario o contraseña que has introducido son incorrectos + Sin avisos No hay ninguna red disponible - No se ha podido eliminar este tema - No se ha podido añadir este tema - Registro de la aplicación - Ha ocurrido un error al crear la base de datos de la aplicación. Por favor, intenta reinstalar la aplicación. - Este blog está oculto y no se puede cargar. Actívalo de nuevo en ajustes y prueba de nuevo. - No se pueden actualizar los medios en este momento + Ha ocurrido un error al acceder a este blog + Error de conexión + Cancelar edición + Aprobado + Pendiente + Spam + En la papelera + Editar comentario + Aprobar + Rechazar + Spam + Enviar a la papelera + ¿Enviar a la papelera? + Papelera + Guardando cambios + Nueva entrada + Añadir nueva categoría + Nombre de la categoría + Cambios locales Blog de WordPress + Ajustes de página Ajustes de imagen - Cambios locales - Nuevo elemento multimedia - Nueva entrada - No hay avisos… aún. - Se necesita autorización - Comprueba que la URL del sitio introducida es válida + Ajustes de entrada + Seleccionar categorías + Texto del enlace (opcional) + Crear un enlace No se pudo crear un archivo temporal para subir el archivo multimedia. Asegúrate que haya suficiente espacio libre en tu dispositivo. - Nombre de la categoría - Añadir nueva categoría + Ocurrió un error al cargar la entrada. Actualiza tus entradas e intenta nuevamente. + Borrador local Ver en el navegador - Eliminar sitio - El comentario no ha cambiado - Comentario obligatorio + Registro de la aplicación + Se necesita autorización + Aprender más ¿Cancelar la edición de este comentario? - Guardando cambios - Papelera - ¿Enviar a la papelera? - Enviar a la papelera - Spam - Rechazar - Aprobar - Editar comentario - En la papelera - Spam - Pendiente - Aprobado - ¿Borrar página? - ¿Borrar entrada? - Ajustes de entrada - No ha sido posible encontrar el archivo a cargar. ¿Se ha borrado o cambiado de ubicación? + Comentario obligatorio + El comentario no ha cambiado Alineación horizontal - Borrador local - Ajustes de página - Crear un enlace - Texto del enlace (opcional) - Algunos medios no se han podido borrar en este momento. Inténtalo de nuevo más tarde. No tienes permiso para ver la librería multimedia - Cuadrícula de miniaturas - Aprender más - Ocurrió un error al cargar la entrada. Actualiza tus entradas e intenta nuevamente. + Este blog está oculto y no se puede cargar. Actívalo de nuevo en ajustes y prueba de nuevo. + Nuevo elemento multimedia + Eliminar sitio + Comprueba que la URL del sitio introducida es válida + No se pueden actualizar los medios en este momento + No ha sido posible encontrar el archivo a cargar. ¿Se ha borrado o cambiado de ubicación? Ocurrió un error al acceder a este plugin - Cancelar edición - Error de conexión - Seleccionar categorías + ¿Borrar entrada? + ¿Borrar página? + No hay avisos… aún. + Algunos medios no se han podido borrar en este momento. Inténtalo de nuevo más tarde. + Ha ocurrido un error al crear la base de datos de la aplicación. Por favor, intenta reinstalar la aplicación. + Cuadrícula de miniaturas + No se ha podido añadir este tema + No se ha podido eliminar este tema Compartir enlace Recuperando entradas… + Comentario no aprobado A ti, y a %,d personas más les gusta esto A %,d personas les gusta esto - No se puede compartir en WordPress si no tienes un blog visible Comentado marcado como spam - Comentario no aprobado + No se puede compartir en WordPress si no tienes un blog visible + Elige una foto + Elige un vídeo No fue posible recuperar esta entrada A ti y a otra persona os gusta esto - Elige un vídeo - Elige una foto - Registro - Imposible abrir %s - Imposible ver la imágen + Contestar al comentario + Añadido %s Imposible compartir - Este no es un tema válido - Ya estás siguiendo este tema No se pudo publicar tu comentario - Te gusta esto - A una persona le gusta esto + Imposible ver la imágen + Imposible abrir %s Eliminado %s - Añadido %s - Contestar al comentario - Siguiendo - Seguir - Compartir - Reblog + Esta lista esta vacía Sin título + Compartir + Seguir + A una persona le gusta esto + Te gusta esto + Siguiendo No hay comentarios aún - Esta lista esta vacía - Meses - Semanas - Días - Ayer - Hoy - Referentes + Reblog + Registro + Este no es un tema válido + Ya estás siguiendo este tema + Temas Etiquetas y categorías - Clics - Estadísticas - Compartir + Hoy + Ayer + Días + Semanas + Meses Activar - No se pudo actualizar - Descripción - Leyenda Título + Descripción + Compartir + Clics + Referentes Pase de diapositivas - Círculos Mosaico + Círculos Cuadrados - Temas - Descartar + Leyenda + No se pudo actualizar + Estadísticas Gestionar - y %d más. - %d nuevos avisos - Seguimientos + Descartar Respuesta publicada + y %d más. Acceder + Seguimientos + %d nuevos avisos Cargando… - Contraseña HTTP Usuario HTTP + Contraseña HTTP Se ha producido un error al cargar los archivos Nombre de usuario o contraseña incorrectos. - Acceder Nombre de usuario Contraseña + Acceder Lector - Incluír imagen en el contenido del mensaje Usar como imagen destacada + Entradas Ancho - Leyenda (opcional) Páginas - Entradas Anónimo + Incluír imagen en el contenido del mensaje No hay red disponible - hecho + Leyenda (opcional) OK + hecho URL Subiendo… Alineación @@ -3479,27 +3479,27 @@ Language: es El nombre del atajo no puede estar vacío. Privado Título - Separa las etiquetas con comas Categorías + Separa las etiquetas con comas Se necesita una tarjeta SD Multimedia Categoría actualizada correctamente. Aprobar Eliminar - Actualizando la categoría que falló Ninguno - Publicar ahora - Responder - en - Vista previa - Error de actualización de categorías + Actualizando la categoría que falló Error - No + Cancelar + Guardar + Añadir + Error de actualización de categorías + Vista previa + Responder + No + en Ajustes de avisos - Añadir - Guardar - Cancelar + Publicar ahora Una vez Dos veces diff --git a/WordPress/src/main/res/values-gl/strings.xml b/WordPress/src/main/res/values-gl/strings.xml index 24524e6d14c2..4dfc3bf36270 100644 --- a/WordPress/src/main/res/values-gl/strings.xml +++ b/WordPress/src/main/res/values-gl/strings.xml @@ -1,11 +1,38 @@ + <b>%1$s</b> está usando %2$s plugins individuais de Jetpack + <b>%1$s</b> está usando o plugin <b>%2$s</b> + A aplicación de WordPress non é compatible cos plugins individuais de Jetpack. + <b>%1$s</b> está usando plugins individuais de Jetpack que non son compatibles coa aplicación de WordPress. + <b>%1$s</b> está usando o plugin <b>%2$s</b>, que non é compatible coa aplicación de WordPress. + Non se puido acceder a algúns dos teus sitios + Non se puido acceder a un dos teus sitios + Por favor, pásate á aplicación Jetpack, onde te guiaremos para que conectes o plugin Jetpack para usar este sitio coa aplicación. + Cambia á aplicación de Jetpack + %1$s usa %2$s, que aínda non é compatible con todas as funcións da aplicación.\n\nInstala o %3$s para usar a aplicación con este sitio. + Este sitio + %1$s usa %2$s, que aínda non é compatible con todas as funcións da aplicación. Instala o %3$s. + %1$s usa %2$s, que aínda non é compatible con todas as funcións da aplicación. Instala o %3$s. + Pásate á aplicación de Jetpack en poucos días. + O cambio é gratuíto e só che levará un minuto. + Eliminamos algunhas funcións (como Estatísticas, Lector ou Notificacións, entre outras) da aplicación de WordPress e, agora, só están dispoñibles na de Jetpack. + Encontrarás máis información en Jetpack.com + Cambia á aplicación de Jetpack + %s trasladáronse á aplicación de Jetpack. + %s trasladouse á aplicación de Jetpack. + WP Admin + Xestionar + Tráfico + Contido + Configurar + Feito + Agora que Jetpack está instalado, só tenemos que configuralo. Só che levará un minuto. Promover unha entrada con Blaze agora Promover esta páxina con Blaze Promover esta entrada con Blaze diff --git a/WordPress/src/main/res/values-ja/strings.xml b/WordPress/src/main/res/values-ja/strings.xml index 185d7b27330a..3ab76f437633 100644 --- a/WordPress/src/main/res/values-ja/strings.xml +++ b/WordPress/src/main/res/values-ja/strings.xml @@ -40,19 +40,19 @@ Language: ja_JP コンテンツは数百万もの WordPress と Tumblr のサイトに表示されます。 1日わずか数百円、たった数分で投稿やページを宣伝できます。 Blaze でサイトのトラフィックを増やす - Blaze このドメインはすでに登録されています セール おすすめ こちらもおすすめ %s/ 年 ヘルプ - FAQ でよくある質問に対する回答をご確認ください。 Jetpack アプリにお切り替えいただきありがとうございます ! ログ チケット 無料 ヘルプ + Blaze + FAQ でよくある質問に対する回答をご確認ください。 ブロックのメニュー 非表示 何百万ものサイトに作品を表示しましょう。 @@ -73,7 +73,6 @@ Language: ja_JP Jetpack は現在インストールできません。 問題が発生しました エラーアイコン - アプリでこのサイトを使用する準備ができました。 Jetpack がインストールされています サイトに Jetpack をインストールしています。 完了まで数分かかります。 Jetpack をインストールしています @@ -82,6 +81,7 @@ Language: ja_JP Jetpack をインストール Jetpack アイコン Blaze を使って宣伝 + アプリでこのサイトを使用する準備ができました。 サイトの可能性を十分に引き出すことができます。 Jetpack で統計や通知などを利用できます。 ご利用のサイトには Jetpack プラグインが設定されています Jetpack モバイルアプリは、Jetpack プラグインと連携させて利用できます。 今すぐ乗り換えて、統計、通知、Reader などをご利用ください。 @@ -231,8 +231,8 @@ Language: ja_JP 統計情報は、Jetpack が提供しています。 新しい Jetpack アプリで利用できる Reader を使用して、お気に入りのサイトや投稿をすべて検索、フォロー、「いいね」できます。 Reader は Jetpack が提供しています。 - 新しい Jetpack アプリには、WordPress をパワーアップできる統計情報、ブログ購読ツール、通知などがあります。 Jetpack で WordPress をパワーアップ + 新しい Jetpack アプリには、WordPress をパワーアップできる統計情報、ブログ購読ツール、通知などがあります。 プランをアップグレードして動画のカバーを使う プランをアップグレードして音声をアップロードする Jetpack 提供 @@ -288,9 +288,9 @@ Language: ja_JP 合計 その他 検索 - WordPress 表示件数 予約 + WordPress 投稿を予約 リマインダーを設定 ブログ投稿のリマインダーを設定 @@ -307,8 +307,8 @@ Language: ja_JP ログインコードをスキャン ⭐️最新の投稿 %1$s が%2$s回「いいね」されました。 アクティビティが足りません。 サイトの訪問者数が増えたら後でもう一度確認してください。 - %1$s人、フォロワー総数のうちの%2$s%% %1$s (%2$s%%) + %1$s人、フォロワー総数のうちの%2$s%% リンクをコピー おめでとうございます ! 詳しくなりました<br/> アプリについて知る @@ -405,10 +405,10 @@ Language: ja_JP 注: ダッシュボードに毎日新しいプロンプトを表示して、アイデアが次々と浮かぶようサポートします ! 執筆の腕を磨くのに一番よい方法は、執筆習慣を身に付け、他の人と共有することです。そこでプロンプトの出番です ! - はじめに\nブログのプロンプト リマインダーを設定 - ブログのプロンプトを含める 定期的に投稿することで、新しい読者を引きつけることができます。 執筆するタイミングを指定していただければ、リマインダーをお送りします ! + はじめに\nブログのプロンプト + ブログのプロンプトを含める 習慣をつけて執筆の腕を磨く 文章と詩 旅行 @@ -440,11 +440,11 @@ Language: ja_JP 美容 自動車 アート - 例: ファッション、詩、政治 サイトのテーマ <b>%1$s</b> をタップして続行します。 - 今日にスキップ プロンプトをさらに表示 + 例: ファッション、詩、政治 + 今日にスキップ %d件の回答 ブログ作成のプロンプトを共有 ✓回答済み @@ -454,8 +454,8 @@ Language: ja_JP この色の組み合わせは読みにくい可能性があります。 背景色を明るくするか、文字の色を暗くしてみましょう。 この色の組み合わせは読みにくい可能性があります。 背景色を暗くするか、文字の色を明るくしてみましょう。 メディアの挿入に失敗しました。\nタップして詳細をご覧ください。 - 以下のリストからテーマを選択するか、自分で入力します。 どのような内容のサイトですか? + 以下のリストからテーマを選択するか、自分で入力します。 1週間のまとめ ホーム カテゴリーを追加しています @@ -484,24 +484,24 @@ Language: ja_JP 「戻る」アイコン Automattic ロゴ WordPress + ソースコード + プライバシーポリシー + 利用規約 + どこでも作業可能 WooCommerce Tumblr Simplenote Pocket Casts Jetpack Day One - ソースコード - プライバシーポリシー - 利用規約 - どこでも作業可能 求人情報 Automattic ファミリー 法的情報およびその他 - Twitter - Instagram 評価してください 友達と共有 このブロックは Web バージョンのエディターを使用して編集できます + Twitter + Instagram Jetpack セキュリティの設定を開く 注: モバイルエディターでこのブロックを編集するには、WordPress.com へのログインを許可する必要があります。 注: レイアウトはテーマ、画面サイズによって異なります @@ -509,9 +509,9 @@ Language: ja_JP メディアを追加 現在、サイトのデータの読み込みに問題が発生しています。 一部のデータを読み込めませんでした - ダッシュボードが更新されていません。 接続を確認してから取り込み、更新してください。 ダッシュボードを更新できませんでした。 動画がアップロードされていません。 5分以上の動画ファイルのアップロードには、有料プランのご利用が必要です。 + ダッシュボードが更新されていません。 接続を確認してから取り込み、更新してください。 謝辞 カリフォルニア州プライバシー通知 バージョン%1$s @@ -527,11 +527,11 @@ Language: ja_JP ダブルタップしてフォントサイズを選択 ダブルタップしてデフォルトのフォントサイズを選択 サポートに問い合わせる - %1$s (%2$s) 会話をフォロー 最初のコメントを投稿 すべてのコメントを表示 投稿データ取得中にエラーが発生しました + %1$s (%2$s) コメント取得中にエラーが発生しました 会話設定をフォロー クリップボードから @@ -576,8 +576,8 @@ Language: ja_JP この会話の購読を解除済み この会話をフォロー中\nアプリ内通知を有効化しますか ? ドメインを検索 - このサイトで購入したドメインを訪問すると <b>%s</b> に転送されます このプランには、1年間の無料ドメイン登録が含まれています + このサイトで購入したドメインを訪問すると <b>%s</b> に転送されます 無料ドメインを取得 ドメインを管理 ドメインを追加 @@ -587,8 +587,8 @@ Language: ja_JP 主要サイトのアドレス サイトのアドレスを変更 あなたの WordPress.com の無料アドレスは - 最初の1年間は<span style=\"color:#B26200;\">%1$s</span><span style=\"color:#50575e;\"><s>%2$s / 年</s></span> %s<span style=\"color:#50575e;\"> / 年</span> + 最初の1年間は<span style=\"color:#B26200;\">%1$s</span><span style=\"color:#50575e;\"><s>%2$s / 年</s></span> 破棄してもよろしいですか ? 保存されていない変更があります コメントは空白にできません @@ -612,14 +612,14 @@ Language: ja_JP <a href=\"\">あなた</a>が「いいね」をつけています。 行の高さ ドメインを取得 - %s おすすめのアプリテンプレートの取得中に不明なエラーが発生しました + %s 無効な応答を受信しました 応答がありませんでした - Automattic アプリ - 各種端末に対応したアプリ WordPress を友達と共有する クイックリンク ドメイン + Automattic アプリ - 各種端末に対応したアプリ 1週間のまとめ: %s 通知時間 <b>毎日</b><b>%s</b>時にブログ投稿のリマインダーを受け取ります。 @@ -642,15 +642,15 @@ Language: ja_JP リッチテキストの編集 異なるブロックの名前を確認したら、フォワードスラッシュに続けてブロック名を入力して (「/image」、「/heading」など)、ブロックを追加します。 画像、gif、動画、埋め込みメディアをページに追加することで、コンテンツを差別化しましょう。 - 投稿やページにブロックをいくつか追加して、どのようになるか見てみましょう。 メディアを埋め込む + 投稿やページにブロックをいくつか追加して、どのようになるか見てみましょう。 各ブロックには独自の設定があります。 確認するには、ブロックをタップします。 画面下部にあるツールバーに設定が表示されます。 レイアウトを構築 ブロックとはコーディングについて知らなくても挿入、配置変更、スタイル設定が実行できる、コンテンツの集まりです。 ブロックを使うことで、簡単かつ洗練された方法で美しいレイアウトに仕上げることができます。 ブロックがあることでコンテンツ作成に集中することができ、メッセージの発信に役立つすべての書式設定ツールが利用できます。 列へのコンテンツの配置、行動喚起ボタンの追加、テキストによる画像のオーバーレイを実行できます。 - 左下のツールバーにある + アイコンをタップして、新しいブロックをいつでも追加できます。 %2$s個中%1$s個が完了 + 左下のツールバーにある + アイコンをタップして、新しいブロックをいつでも追加できます。 簡単なチュートリアルで基本を学びましょう。 1つ以上のコメントを承認できませんでした サイトを作成 @@ -672,8 +672,8 @@ Language: ja_JP ダブルタップで固定ページをプレビューできます。 訪問者のブラウザータブやオンライン上のその他の場所に表示されます。 表示 - アプリでこのサイトを管理する方法をしりたいですか ? 新規サイトを作成 + アプリでこのサイトを管理する方法をしりたいですか ? サイトはいつでも切り替えることができます。 開くサイトを選択 現在、Jetpack スキャンは WordPress のマルチサイトインストールとの互換性がありません。 @@ -689,9 +689,9 @@ Language: ja_JP ブログを投稿する日を選択します 「自分のサイト」 > 「設定」 > 「ブログのリマインダー」からいつでも更新できます。 リマインダーが設定されていません。 - 週に%1$s回、%2$s曜日の%3$s時にブログ投稿のリマインダーを受け取ります。 リマインダーを削除しました。 設定を完了しました。 + 週に%1$s回、%2$s曜日の%3$s時にブログ投稿のリマインダーを受け取ります。 更新 設定なし 週に%s @@ -704,17 +704,17 @@ Language: ja_JP 再利用ブロックの編集は WordPress for iOS ではまだサポートされていません 再利用ブロックの編集は WordPress for Android ではまだサポートされていません 「通常のブロックへ変換」をタップして、これらのブロックを個別に切り離して編集できます。 - 完了 通知する + 完了 <a href=\"%1$s\">サーバーのログイン情報</a>を入力すると、1クリックでバックアップからサイトを復元できるようになります。 - アイキャッチ画像として設定 - アイキャッチ画像を削除 カテゴリーを作成 WordPress for Android サポート + アイキャッチ画像として設定 + アイキャッチ画像を削除 サイトのカテゴリーを管理 カテゴリー - リマインダー 最新の投稿ページのコンテンツは自動的に生成され、編集することはできません。 + リマインダー 枠線設定 今後表示しない ストレージを表示 @@ -737,8 +737,8 @@ Language: ja_JP アクションシートをダブルタップして開き、画像や動画を追加 現在のユニットは%s クロスポスト - %s が通常のブロックに変換されました カラム設定 + %s が通常のブロックに変換されました %s にリンクを追加 リンク文字列を追加 画像または動画を追加 @@ -755,14 +755,14 @@ Language: ja_JP すでにサイトをお持ちの場合は、無料の Jetpack プラグインをインストールし、WordPress.com アカウントに接続する必要があります。 自分のプロフィール写真 %1$sにこのアプリを使用するには、Jetpack プラグインをインストールし、自身の WordPress アカウントに接続する必要があります。 - 画像を前に移動 画像を後ろに移動 + 画像を前に移動 幅設定 - リンク rel カラム設定 - (無題) - サイト + リンク rel ユーザープロフィールボトムシート情報 + サイト + (無題) いいねリスト%s 2 3 @@ -777,31 +777,30 @@ Language: ja_JP 利用できるプレビューがありません テキスト色 パディング - 4 おすすめ - カスタム URL + 4 埋め込みを作成 + カスタム URL カラム %d スクリーンリーダーのユーザーを支援するため、リンクについて簡単に説明してください ブロックを追加 Jetpack サイトが見つかりませんでした 代替テキストとは ? - %sを変換: ブロックを変換… + %sを変換: メディアの挿入に失敗しました。 音声ファイルの挿入に失敗しました。 - 画像の目的を説明します。 画像が単にデザインである場合は、空欄のままにします。 - %1$sを%2$sに変換しました 「いいね」データの読み込みに失敗しました。%s。 %d個の「いいね」 - 1個の「いいね」 + %1$sを%2$sに変換しました + 画像の目的を説明します。 画像が単にデザインである場合は、空欄のままにします。 提案: + 1個の「いいね」 アイコンボタンを使用 検索入力フィールドです。 検索ボタンです。 現在のボタンテキストは 検索ブロック 検索ブロックラベルです。 現在のテキストは - 外側 カスタムプレースホルダーの設定なし 内側 検索見出しを非表示 @@ -809,6 +808,7 @@ Language: ja_JP ダブルタップしてラベルテキストを編集 ダブルタップしてボタンテキストを編集 ダブルタップして単位を変更 + 外側 現在のプレースホルダーテキストは 検索をクリア 検索をキャンセル @@ -819,10 +819,10 @@ Language: ja_JP 利用可能なネットワークがありません。 未返信のコメント 未返信 - リンクを追加 検索設定 - 常時許可 IP アドレス + リンクを追加 禁止コメント + 常時許可 IP アドレス ボタンのテキストを追加 トピックをフォロー 心をつかむコンテンツを作り、サイトで公開する新しい方法。 @@ -833,42 +833,42 @@ Language: ja_JP スキャンで %2$s に%1$s個の潜在的な脅威が見つかりました。以下の内容を確認して操作するか、すべて修正ボタンをタップしてください。 必要な場合は、%3$sにご連絡ください。 現在バックグラウンドでこれらの脅威を修正しています。その間、通常通りサイトを使用し、いつでも進行状況を確認できます。 焦点を編集 - ダブルタップして「ボトムシート」を開き、画像を編集、置換、クリアする - ダブルタップして「アクションシート」を開き、画像を編集、置換、クリアする example.com サイトの名前を入力してください <b>全タスク完了</b><br/>より多くの人に発信できるでしょう。素晴らしいです ! + ダブルタップして「ボトムシート」を開き、画像を編集、置換、クリアする + ダブルタップして「アクションシート」を開き、画像を編集、置換、クリアする <b>全タスク完了</b><br/>サイトをカスタマイズしました。いい感じです ! - 今は非表示にする 新しいアカウントを作成しない場合は、 戻ってメールアドレスを再度入力してください。 招待リンクを無効化すると、このリンクを使用してチームに参加できなくなります。本当に実行しますか ? + 今は非表示にする 招待リンクを無効化 無効な応答を受信しました 応答がありませんでした - 権限グループ「%1$s」のデータ取得中にエラーが発生しました - 権限グループの取得中にエラーが発生しました - 招待リンクデータの取得中に不明なエラーが発生しました このリンクを使用すると、チームメンバーを1人ずつではなく一括で招待できます。 {{strong}}この URL にアクセスすると、だれでも組織に登録されます。{{/strong}}リンクをだれから受け取ったかは関係ないため、信頼できる人と共有するようにしてください。 - %1$sに期限切れ + 招待リンクデータの取得中に不明なエラーが発生しました + 権限グループの取得中にエラーが発生しました + 権限グループ「%1$s」のデータ取得中にエラーが発生しました 招待リンクを無効化 招待リンクを共有 新規リンクを作成 リンクのステータスを更新 招待リンク + %1$sに期限切れ 検出された脅威 検出された脅威 - <b>スキャン完了</b> <br></br> %s件の潜在的な脅威が見つかりました <b>スキャン完了</b> <br></br> 1件の潜在的な脅威が見つかりました <b>スキャン完了</b> <br></br>脅威は見つかりませんでした - 脅威の修正 + <b>スキャン完了</b> <br></br> %s件の潜在的な脅威が見つかりました 無効化 - これを固定解除 + 脅威の修正 ページをチェックして変更を加えたり、ページを追加または削除したりしましょう。 + これを固定解除 サイトを表示 参考になるサイトを探してフォローしましょう。 - ソーシャル共有 新しい投稿を自分のソーシャルメディアと自動的に共有しましょう。 サイトにその特徴とトピックがわかるような名前を付けてください。 + ソーシャル共有 サイト統計情報を確認 ダウンロード可能なバックアップファイルの作成を試みます。 ダウンロード可能なバックアップにかかる時間を示すステータスが見つかりませんでした。 @@ -920,50 +920,50 @@ Language: ja_JP セキュリティの脅威が検出されたら通知を送信します。その間、通常通りサイトを使用し、いつでも進行状況を確認できます。 脅威の修正 Jetpack Scan はサイトのスキャンを完了できませんでした。 サイトがダウンしていないか確認してください。ダウンしていない場合、再度実行してください。 ダウンしている場合、または Jetpack Scan に問題がある場合、サポートチームまでご連絡ください。 - 問題が発生しました サイトのバックアップ %1$s %2$sからサイトをバックアップしています ダウンロード可能なバックアップの作成 サイトは正常にバックアップされました + 問題が発生しました サイトは正常にバックアップされました\n%1$s %2$sからバックアップ サイトをバックアップしています\n%1$s %2$sからバックアップしています 音声ファイルを選択 - 実行中の復元が他にあります。 エラーアイコン 完了ボタン - 復元失敗 + 実行中の復元が他にあります。 + サイトを復元しました サイトを表示ボタン - 完了ボタン - 復元アイコン サイトを表示 + 復元アイコン + 復元失敗 + 完了ボタン 選択したすべてのアイテムは %1$s %2$s に復元されました。 - サイトを復元しました お待ちいただく必要はありません。 サイトが完全に復元されたらお知らせします。 サイト復元アイコン - サイトを %1$s %2$s に復元しています。 現在サイトを復元中 サイト復元確認ボタン - 感嘆符付きの赤くて丸い画像 + サイトを %1$s %2$s に復元しています。 警告 サイト復元ボタン - 復元アイコン - サイトを復元 - 復元用ポイントとして%1$s %2$sを選択しています。 + 感嘆符付きの赤くて丸い画像 サイトを復元 - 復元するアイテムを選択: + サイトを復元 + 復元アイコン 復元 - クラウドと X のアイコン 完了ボタン 完了 - ダウンロード失敗 + クラウドと X のアイコン + 復元用ポイントとして%1$s %2$sを選択しています。 + 復元するアイテムを選択: タブレット モバイル + ダウンロード失敗 二度と表示しない - 上部固定 %1$s ページ %2$s を選択してページリストを表示します。 サイトのページを変更、追加、削除します。 サイトページをレビュー %1$s ホームページ %2$s を選択してホームページを編集します。 + 上部固定 未読にする 既読にする メディアのアップロードに失敗しました。\n%1$s @@ -975,24 +975,24 @@ Language: ja_JP 脅威は正常に修正されました。 脅威を修正する際にエラーが発生しました。 サポートにご連絡ください。 1件のアクティブな脅威を修正してよろしいですか ? + 脅威を無視しました。 すべての脅威を修正 脅威を無視する際にエラーが発生しました。 サポートにご連絡ください。 - 脅威を無視しました。 安全であるという確信がない限り、セキュリティの問題を無視しないでください。 この脅威を無視した場合、この脅威はサイト <b>%s</b> に残ります。 脅威を修正する際にエラーが発生しました。 サポートにご連絡ください。 脅威を無視しました - 次の日時に脅威を修正済み %s - 脅威を修正 - 無視済み - 項目が見つかりませんでした - 固定 - すべて サイトをスキャン中 + スキャン履歴 スキャン準備中 + 項目が見つかりませんでした + 無視済み 履歴 - スキャン履歴 + 脅威を修正 + 固定 + すべて 期間を調整してみてください 一致するバックアップは見つかりませんでした + 次の日時に脅威を修正済み %s 初回のバックアップは24時間以内にここに表示され、バックアップが完了すると通知が送信されます 最初のバックアップがもうすぐ完了します リクエストの処理中に問題が発生しました。 後ほどもう一度お試しください。 @@ -1009,10 +1009,10 @@ Language: ja_JP %1$s %2$s からサイトのバックアップが正常に作成されました。 バックアップをダウンロードする準備が整いました バックアップ - お待ちいただく必要はありません。 バックアップが完了したら通知します。 ダウンロード可能なバックアップを作成中アイコン %1$s %2$s からダウンロード可能なサイトのバックアップを作成中です。 現在、サイトのダウンロード可能なバックアップを作成中です + お待ちいただく必要はありません。 バックアップが完了したら通知します。 バックアップをダウンロードする 別のダウンロードを実行中です。 リクエストの処理中に問題が発生しました。 後ほど、もう一度お試しください。 @@ -1023,10 +1023,6 @@ Language: ja_JP %1$s · クロス投稿 ユーザー - 一致する %s はありません。 - 提案の読み込みに問題がありました。 - 利用できる %s の提案はありません。 - おすすめリストをフィルターするには入力してください。 無料の見積もりを受ける 脅威を無視する 脅威を修正する @@ -1034,6 +1030,10 @@ Language: ja_JP Jetpack Scan は影響を受けるファイルまたはディレクトリを編集します。 Jetpack スキャンは新しいバージョン (%s) に更新されます。 Jetpack スキャンは影響を受けるファイルまたはディレクトリを削除します。 + 一致する %s はありません。 + 提案の読み込みに問題がありました。 + 利用できる %s の提案はありません。 + おすすめリストをフィルターするには入力してください。 Jetpack スキャンは影響を受けるファイルまたはディレクトリを置き換えます。 Jetpack スキャンは、この脅威を自動的に修正できません。\n 脅威を手動で解決することを推奨します : WordPress、テーマ、すべてのプラグインが最新であることを確認し、問題の原因となるコード、テーマ、プラグインをサイトから削除します。 \n \n\nこの脅威の解決においてさらにサポートが必要な場合は、厳選された WordPress エキスパートによる信頼性の高いフリーランス向けマーケットプレイス、<b>Codeable</b> をおすすめします。\n これらのプロジェクトを支援するセキュリティエキスパートの厳選されたグループが登録されています。 価格は1時間あたり $70~120で、無料の見積もりを受けることができます。利用を開始する義務はありません。 脅威の解決 @@ -1043,46 +1043,46 @@ Language: ja_JP 技術詳細 問題は何でしたか ? 脅威の詳細 - テーマに脆弱性を発見 - プラグインに脆弱性を発見 脅威を検出しました %s WordPress で脆弱性が見つかりました 様々な脆弱性 - 脆弱なテーマ: %1$s (バージョン%2$s) - 脆弱なプラグイン: %1$s (バージョン%2$s) %s: 不正なコードパターン データベース %s 脅威 + テーマに脆弱性を発見 + プラグインに脆弱性を発見 + 脆弱なテーマ: %1$s (バージョン%2$s) + 脆弱なプラグイン: %1$s (バージョン%2$s) %s: 感染したコアファイル 脅威を検出しました すべて修正 - 数秒前 %s分前 %s時間前 このサイト + 数秒前 前回の Jetpack スキャンは%1$sに実行され、リスクは見つかりませんでした。 %2$s - サイトが危険にさらされている可能性があります ご心配は無用です 再スキャン 今すぐスキャン スキャン状態のアイコン バックアップ アクティビティタイプフィルター (%sタイプが選択されています) - %1$s (%2$s項目を表示しています) + サイトが危険にさらされている可能性があります アクティビティタイプフィルター 選択した日付の間に記録されたアクティビティはありません。 アクティビティはありません インターネット接続を確認し、もう一度お試しください。 + %1$s (%2$s項目を表示しています) 接続できません アクティビティタイプ (%s) 日付の範囲フィルター データ範囲またはアクティビティタイプフィルターを調整してみてください 一致するイベントは見つかりませんでした - サイトデータベース - (wp-config.php と WordPress 以外のすべてのファイルを含む) メディアのアップロード WordPress プラグイン WordPress テーマ ダウンロード可能なバックアップアイコンを作成 + サイトデータベース + (wp-config.php と WordPress 以外のすべてのファイルを含む) ダウンロード可能なファイルを作成 ダウンロード可能なバックアップを作成 バックアップをダウンロードする @@ -1091,8 +1091,8 @@ Language: ja_JP ファイルを選択 バックアップをダウンロード このポイントに復元 - アクティビティタイプ 日付の範囲 + アクティビティタイプ アクティビティタイプで絞り込み このアプリからバージョンをコピー 最初に投稿を編集する @@ -1110,11 +1110,11 @@ Language: ja_JP ドメインを選択 Jetpack 設定 Jetpack - メールで会話をフォロー中 - メールで会話をフォロー この投稿のコメントをフォロー解除できませんでした この投稿のコメントをフォローできませんでした 投稿の購読ステータスを取得中にエラーが発生しました + メールで会話をフォロー + メールで会話をフォロー中 無効な応答を受信しました 応答がありませんでした クリア @@ -1136,10 +1136,10 @@ Language: ja_JP 終了 次へ 削除 - テーマの選択中にエラーが発生しました。 ネットワーク接続を確認して、もう一度お試しください。 オンラインに戻ったら、「再試行」をタップします。 レイアウトはオフラインでは利用できません + テーマの選択中にエラーが発生しました。 ストアのログイン情報で続ける 連携済みのメールアドレスを検索 トピックをフォロー @@ -1178,9 +1178,9 @@ Language: ja_JP インスピレーションを受ける お気に入りのサイトをフォローして新しい読み物を発見しましょう。 詳細な分析により、オーディエンスの成長を見守れます。 - コメントと通知をリアルタイムで表示します。 強力なエディターで、外出中も投稿できます。 世界で最も人気のサイト構築サービスへようこそ。 + コメントと通知をリアルタイムで表示します。 メディア読み込み失敗 フォローするサイト リリースごとにブロックを追加できるよう努めています。 @@ -1215,55 +1215,55 @@ Language: ja_JP メディアをアップロード中 検索または URL を入力 この電話リンクを追加 - このリンクを追加 このメールリンクを追加 + このリンクを追加 インターネットに接続していません。\n提案が利用できません。 - 太字 - モダン - プレイフル 強調 - クラシック + プレイフル + モダン カジュアル - 動画を録画するには、アプリに音声録音の権限を付与する必要があります + クラシック %s %sを選択済み - ログインリンクをメールで取得 - このメールアドレスに紐付けられている WordPress.com アカウントが見つかりません。 - マイク + 動画を録画するには、アプリに音声録音の権限を付与する必要があります + 太字 このコメントを表示できません + マイク + ログインリンクをメールで取得 項目を閲覧 + このメールアドレスに紐付けられている WordPress.com アカウントが見つかりません。 この投稿を報告 - Reader へようこそ。何百万ものブログの中から、お気に入りを発見しましょう。 内部サーバーエラーが発生しました 操作は許可されていません %1$s 件のアイテムをさらに表示 + Reader へようこそ。何百万ものブログの中から、お気に入りを発見しましょう。 レイアウトを選択 注: カラムのレイアウトはテーマ、画面サイズによって異なります - 投稿またはストーリーを作成 - ページを作成 投稿を作成 - おすすめ + ページを作成 非表示 + おすすめ + 投稿またはストーリーを作成 動画の見出しです。 空にする タイトルを更新します。 ページタイトルの後に ブロックを貼り付けます。 %s ページタイトル。 空にする 動画再生時にエラーが発生しました - この端末は Camera2 API をサポートしていません。 動画を保存できませんでした 画像を保存する際にエラーが発生しました 操作が進行中です。再度お試しください ストーリースライドが見つかりませんでした ストレージを表示 - 公開する前に端末にストーリーを保存する必要があります。ストレージ設定を確認し、ファイルを削除してスペースを空けてください。 - 端末のストレージ容量が足りません + この端末は Camera2 API をサポートしていません。 スライドの保存または削除を再度試してから、ストーリーの公開を再度試してみてください。 %1$dつのスライドを保存できません 1つのスライドを保存できません 管理 %1$d つのスライドで操作が必要です 1つのスライドで操作が必要です + 端末のストレージ容量が足りません + 公開する前に端末にストーリーを保存する必要があります。ストレージ設定を確認し、ファイルを削除してスペースを空けてください。 「%1$s」をアップロードできません 「%1$s」をアップロードできません 「%1$s」を公開しました @@ -1309,26 +1309,26 @@ Language: ja_JP 事前に用意されたさまざまなページレイアウトを選ぶところから始めましょう。 空白ページから始めることもできます。 レイアウトを選択 ストーリーにタイトルを付ける - 投稿またはストーリーを作成 投稿、ページ、ストーリーを作成 + 投稿またはストーリーを作成 「%1$s 作成」をタップします。%2$s 次に「<b>ブログ投稿</b>」を選択します - 端末から選択 ストーリー投稿 インストール型の WordPress サイトでサイトアイコンを編集するには Jetpack プラグインが必要です。 リンクされたページジャンプが見つかりません ファイルをアップロードできません。\nストレージ割り当ての上限に達しました。 ストレージ割り当ての上限に達しました + 端末から選択 ファイルを追加 動画を置換 画像または動画を置換 - リンクに変換 動画を選択 画像または動画を選択 画像を選択 削除したブロック - 既存のサイトアドレスを入力 登録の確認 Google を引き続き使用し、WordPress.com アカウントをまだお持ちでない場合は、アカウントを作成して WordPress.com の%1$s利用規約%2$sに同意します。 + 既存のサイトアドレスを入力 + リンクに変換 継続することで、%1$s利用規約%2$sに合意したことになります。 このメールアドレスは新しい WordPress.com アカウントの作成に使用します。 新しい WordPress.com アカウントを作成するための登録リンクをメールでお送りしました。現在の端末でメールをチェックし、WordPress.com から届いたメールにあるリンクをタップしてください。 @@ -1338,21 +1338,20 @@ Language: ja_JP サイトアドレスを検索 終了 メールが表示されない場合は、 スパムメールや迷惑メールのフォルダーを確認してください。 - この端末でメールをチェックして、WordPress.com から届いたメールにあるリンクをタップしてください。 パスワードなしですぐにログインできるリンクのメールをお送りします。 + この端末でメールをチェックして、WordPress.com から届いたメールにあるリンクをタップしてください。 メールを確認 今すぐ始める メールアドレスを入力してログインするか、WordPress.com アカウントを作成します。 - またはパスワードを入力 アカウントを作成 リンクをメールで送信 パスワードをリセット + またはパスワードを入力 リクエストの処理中に問題が発生しました。 後ほど、もう一度お試しください。 - サイトタイトルを確認 新しいタイトルを設定するには<b>%1$s</b>をタップしてください + サイトタイトルを確認 この投稿をゴミ箱に移動するとローカルの変更も破棄されます。続行してもよいですか ? %s ブロックオプション - ブロックを削除 ブロックを複製 ブロックをコピー コピーしたブロック @@ -1361,6 +1360,7 @@ Language: ja_JP ブロックを切り取りました ブロックをコピーしました サイトのタイトルを変更できるのは管理者の役割を持つユーザーだけです。 + ブロックを削除 サイトのタイトルは、Web ブラウザーのタイトルバーに表示され、ほとんどのテーマのヘッダーに表示されます。 トピック サイトのタイトルを更新できませんでした。 ネットワーク接続を確認して、もう一度お試しください。 @@ -1374,14 +1374,13 @@ Language: ja_JP ダブルタップしてオプションを選択 グラデーションをカスタマイズ ページ作成者 + 自分 メディアサムネイルを読み込めませんでした - コンテンツ構造 誰でも - 自分 + コンテンツ構造 非表示 未設定 タグは、投稿の内容を読者に伝えるのに役立ちます。 - 公開日 タグを追加 戻る 今すぐ保存 @@ -1392,8 +1391,8 @@ Language: ja_JP 公開日 キャンセル 下書きに移動 + 公開日 ゴミ箱にある投稿は編集できません。この投稿のステータスを「下書き」に戻して編集しますか ? - 投稿を下書きに移動しますか ? 関心のあるものを選択 関心のあるものを選択 終了 @@ -1404,6 +1403,7 @@ Language: ja_JP 公開日 CCPA のプライバシー通知を読む カリフォルニア州消費者プライバシー法 (CCPA) は、収集および共有する個人情報の分類、その個人情報を取得する場所、その使用方法と目的についての詳細情報をカリフォルニア州の住民に提供することを企業に義務づけています。 + 投稿を下書きに移動しますか ? カリフォルニア州のユーザーへのプライバシー通知 ステータスと公開状態 今すぐ更新 @@ -1412,25 +1412,25 @@ Language: ja_JP メンションを挿入 ダブルタップして「下部シート」と利用可能オプションを開く ダブルタップして「アクションシート」と利用可能オプションを開く + ページを選択 現在、一時的にページを開けません。後ほどもう一度お試しください + 投稿ページ 投稿ページとして設定 ホームページに設定する - %1$s は有効な %2$s ではありません - ページを選択 - 投稿ページ 固定ホームページ クラシックブログ ホームページと投稿用ページは同じものを選択できません。 - ホームページ設定の更新に失敗しました。インターネット接続を確認してください - ページを読み込む前にホームページ設定の保存はできません - ホームページ設定を保存できません + %1$s は有効な %2$s ではありません 承認 + ホームページ設定を保存できません + ホームページ設定 + ページを読み込む前にホームページ設定の保存はできません ページの読み込みに失敗しました 最新の投稿を表示するホームページ (クラシックブログ) か固定ページから選択してください。 - ホームページ設定 + ホームページ設定の更新に失敗しました。インターネット接続を確認してください ホームページ - 投稿ページの更新に失敗しました 投稿ページの更新に成功しました + 投稿ページの更新に失敗しました ホームページの更新に失敗しました ホームページが正常に更新されました 「サイト設定」で「投稿」ページを「固定ホームページ」にするには @@ -1438,8 +1438,6 @@ Language: ja_JP 色を選択 ダブルタップして色設定に移動 サイトをフォローすると、こちらにコンテンツが表示されます - さらに詳しく - %s の新機能 %d を挿入 切り取り ファイルに読み込めませんでした。もう一度お試しください。 @@ -1449,6 +1447,8 @@ Language: ja_JP メディアを選択 動画を選択 サイトを選択できませんでした。もう一度お試しください。 + さらに詳しく + %s の新機能 次へ リブログに失敗しました サイトの管理 @@ -1469,13 +1469,13 @@ Language: ja_JP ブロックを左に移動 ダブルタップしてブロックを右に移動 ダブルタップしてブロックを左に移動 - ブロックの設定 ダッシュボードの作成 テーマを設定する サイト機能の追加 サイト URL を取得 まもなくサイトの準備が完了します 成功しました。\nほぼ終了 + ブロックの設定 アップロードのキャンセル リクエストの処理中に問題が発生しました Powered by Tenor @@ -1490,12 +1490,12 @@ Language: ja_JP 非公開サイトのコンテンツにアクセスできませんでした。一部のメディアは利用できない場合があります 非公開サイトのコンテンツへのアクセス 画像の切り抜きと保存に失敗しました。もう一度お試しください。 - 画像の読み込みに失敗しました。\nタップして再試行してください。 画像をプレビュー ページのフォーマットが不明です この操作を完了できなかったため、この確認用のページは送信されていません。 この操作を完了できなかったため、このページのスケジュールは設定されていません。 この操作を完了できなかったため、この非公開ページは公開されていません。 + 画像の読み込みに失敗しました。\nタップして再試行してください。 この操作を完了できなかったため、このページは公開されていません。 この確認用のページを送信できませんでした。後ほど再実行します。 このページのスケジュールを設定できませんでした。後ほど再実行します。 @@ -1507,16 +1507,15 @@ Language: ja_JP このメディアをアップロードできなかったため、ページは公開されていません。 端末が再びオンラインになった時に、下書きを保存します 端末が再びオンラインになった時に、非公開のページを公開します。 - 端末が再びオンラインになった時に、ページの予約投稿を行います。 - 端末が再びオンラインになった時に、ページのレビュー申請を送信します。 - 端末が再びオンラインになった時に、ページを公開します。 キューに入っているページ ページをアップロード中 - 端末がオフラインです。ページはローカルに保存されました。 このページに保存されていない変更が加えられました + 端末が再びオンラインになった時に、ページを公開します。 + 端末が再びオンラインになった時に、ページのレビュー申請を送信します。 + 端末が再びオンラインになった時に、ページの予約投稿を行います。 + 端末がオフラインです。ページはローカルに保存されました。 ページのアップロード中 ページはメディアアップロードに失敗し、ローカルに保存されました - ページを端末に保存しました ページはオンラインで保存されました QuickPress ショートカット用のブログを選択 バッテリーセーバーで設定 @@ -1524,6 +1523,7 @@ Language: ja_JP ライト 外観 このページに最近変更が加えられましたが、保存されませんでした。読み込むバージョンを選択します。\n\n + ページを端末に保存しました 投稿の内容を表示 抜粋のみを表示 リンク先 @@ -1538,8 +1538,8 @@ Language: ja_JP ゴミ箱に移動済み 予約済み 公開済み - Facebook との連携でページが見つかりません。 Jetpack ソーシャルで Facebook のプロフィールに連携できません。連携できるのは公開されているページのみです。 接続されていません + Facebook との連携でページが見つかりません。 Jetpack ソーシャルで Facebook のプロフィールに連携できません。連携できるのは公開されているページのみです。 いいね フォロー コメント @@ -1551,23 +1551,23 @@ Language: ja_JP 全般 新しいカードを追加 新しい統計カードを追加 - フィルターボタンを使って指定トピックの投稿を検索 - タグまたはサイトを選択 (ポップアップウィンドウ) - 投稿を絞り込むためのサイトまたはタグを選択 + WordPress.com にログイン 現在のフィルターを削除 + 投稿を絞り込むためのサイトまたはタグを選択 + タグまたはサイトを選択 (ポップアップウィンドウ) + フィルターボタンを使って指定トピックの投稿を検索 トピックとサイトを管理 - WordPress.com にログイン - WordPress.com にログインし、フォロー中のトピックの最新投稿をチェック WordPress.com にログインし、フォロー中のサイトの最新投稿をチェック + WordPress.com にログインし、フォロー中のトピックの最新投稿をチェック 現在のブロックを置き換え 末尾に追加 先頭に追加 前にブロックを追加 後にブロックを追加 - トピックを追加 サイトをフォロー - トピックを追加すると、特定の内容に関する投稿をフォローできます フォローしているサイトの最新の投稿を表示 + トピックを追加 + トピックを追加すると、特定の内容に関する投稿をフォローできます フォロー中 フィルター 動画の見出しです。%s @@ -1589,16 +1589,16 @@ Language: ja_JP %1$s、%2$d %3$s ギャラリーのキャプション。%s 投稿またはページを作成 - サイトを構築する人 今はしない + サイトを構築する人 どんなものを作成や共有する場合でも、ここでお手伝いします。 WordPress へようこそ - フォトライブラリ 画像の選択を解除しました + フォトライブラリ + ブログ投稿 + 画像サムネイル 、選択済 画像を選択しました - 画像サムネイル - ブログ投稿 新規追加 公開 今すぐ同期 @@ -1611,24 +1611,23 @@ Language: ja_JP <b>HTTP 認証</b>の問題により、サイトにアクセスできませんでした。ホストに問い合わせてこの問題を解決してください。 サイトの <b>XMLRPC ファイル</b>にアクセスできませんでした。ホストに問い合わせてこの問題を解決してください。 もう少しです !最後に、Jetpack に連携したメールアドレス <b>%1$s</b> を確認します - %1$s サイトのアカウント情報でログイン - サイトのページ フォロー中 + サイトのページ + %1$s サイトのアカウント情報でログイン + 現在、投稿を開くことができません。後ほど、もう一度お試しください + %sB + %sM + %sQa + %sT + %sQi + サイト + 保存しました いいね + 現在、サイトのデータを読み込めません。後ほど、もう一度お試しください ディスカバー - 保存しました トピック - サイト - %sQi - %sQa - %sT - %sB - %sM %sK - 現在、投稿を開くことができません。後ほど、もう一度お試しください - 現在、サイトのデータを読み込めません。後ほど、もう一度お試しください WordPress メディアライブラリ - 非サポート グループ解除 タップしてキーボードを非表示 タップしてヘルプを表示 @@ -1636,10 +1635,10 @@ Language: ja_JP 写真または動画を撮る 写真を撮る 執筆を開始… + 非サポート %sブロック。このブロックは無効なコンテンツです %sブロック。空 ブロックを切り取る - 動画を開く際に問題が発生しました ブロックの表示中に問題が発生しました 投稿タイトル。%s 投稿タイトル。空 @@ -1647,17 +1646,18 @@ Language: ja_JP 改ページブロック。%s 設定を開く このリクエストを処理できるアプリケーションはありません。Web ブラウザーをインストールしてください。 + 動画を開く際に問題が発生しました 上に移動 ブロックを行 %1$s から行 %2$s に上に移動します ブロックを上に移動 ブロックを行 %1$s から行 %2$s に下に移動します ブロックを下に移動 - リンクテキスト リンクを挿入しました 画像キャプション。%s キーボードを非表示 ヘルプアイコン ダブルタップして前回の変更を元に戻す + リンクテキスト ダブルタップして設定を切り替え ダブルタップして画像を選択 ダブルタップして動画を選択 @@ -1670,25 +1670,25 @@ Language: ja_JP ダブルタップと長押しで編集 現在の値 %s 端末から選択 - 不明なエラーが発生しました。もう一度お試しください。 - 代替テキスト - 動画を追加 - URL を追加 - 代替テキストを追加 画像または動画を追加 + URL を追加 + 動画を追加 + 代替テキスト 画像を追加 ここにブロックを追加 + 不明なエラーが発生しました。もう一度お試しください。 + 代替テキストを追加 「Add to Save Posts」ボタンをタップし、投稿をリストに保存します。 「リストに %1$d 項目が読み込まれました」 通知 - オフ - オン このサイトの通知をオフにすると、このサイトの通知タブでは通知表示が無効になります。サイトの通知をオンにすると、表示される通知の種類を調整できます。 - このサイトの通知タブで通知を表示するには、このサイトの通知をオンにしてください。 - このサイトの通知タブで通知表示を有効化 - このサイトの通知タブで通知表示を無効化 + オン + オフ このサイトの通知 このサイトの通知 + このサイトの通知タブで通知表示を無効化 + このサイトの通知タブで通知表示を有効化 + このサイトの通知タブで通知を表示するには、このサイトの通知をオンにしてください。 画像または動画を追加 このレビュー投稿を送信できませんでした。後ほど再度実行します。 この投稿を予約投稿にできませんでした。後ほど再度実行します。 @@ -1711,26 +1711,26 @@ Language: ja_JP プレビューは利用できません プレビュー前に投稿を保存する際のエラー プレビューを生成中… - 保存中… この投稿に保存されていない変更が加えられました + 保存中… このアプリからのバージョン - 他の端末からのバージョン - このアプリから\n%1$s\n に保存しました\nほかのデバイスから\n%2$s\n に保存しました\n この投稿に最近変更が加えられましたが、保存されませんでした。読み込むバージョンを選択します。\n\n どのバージョンを編集しますか ? 完全に削除 下書きに加えた最新の変更を保存しません。 + 他の端末からのバージョン + このアプリから\n%1$s\n に保存しました\nほかのデバイスから\n%2$s\n に保存しました\n これらの変更を予約しません。 レビューに対するこれらの変更を送信しません。 これらの変更を公開しません。 端末が再びオンラインになった時に、下書きを保存します 端末が再びオンラインになった時に、非公開の投稿を公開します。 - 端末が再びオンラインになった時に、投稿の予約投稿を行います。 端末が再びオンラインになった時に、投稿のレビュー申請を送信します。 + 端末が再びオンラインになった時に、投稿の予約投稿を行います。 端末が再びオンラインになった時に、投稿を公開します。 この操作はキャンセルできません。ユーザー名はすでに更新されている可能性があります。 - 新しいユーザー名は %1$s です ユーザー名を保存しています… + 新しいユーザー名は %1$s です ユーザー名を変更する ユーザー名を %1$s%2$s%3$s に変更します。ユーザー名を変更すると、Gravatar プロフィールと IntenseDebate プロフィールのアドレスも変更されます。変更後のユーザー名を確認して続行してください。 ご注意ください。 @@ -1765,9 +1765,9 @@ Language: ja_JP 共有する 戻る 進む - 「%1$s」は %3$s アプリの「%2$s」での公開が予定されています\n %4$s WordPress の予約済み投稿 :「%s」 「%s」は10分後に公開されます + 「%1$s」は %3$s アプリの「%2$s」での公開が予定されています\n %4$s 「%s」は1時間後に公開されます 「%s」が公開されました 予約済みの投稿 :10分前のリマインダー @@ -1783,7 +1783,6 @@ Language: ja_JP 日付と時刻 ウェブサイトの完全なアドレス (例 : example.com) を入力してください。 WordPress.com でログインして、%1$s に接続してください - 表示数 投稿 %1$s:%2$s、%3$s:%4$s 項目を非表示にしました @@ -1794,6 +1793,7 @@ Language: ja_JP 次の期間の %1$s %2$s :%3$s、前の期間からの変更 - %4$s 選択したカードデータの読み込み エディター + 表示数 拡大 折りたたむ メールアドレスを検証してください。ご登録のメールアドレスに指示が送信されました @@ -1807,27 +1807,27 @@ Language: ja_JP メディアをアップロードしています。\nタップすると、オプションが表示されます。 リンクを新しいウィンドウまたはタブで開く 統計情報を表示するには、WordPress.com アカウントにログインしてください。 - 検索に一致する投稿はありません + 全期間 + 今日 投稿を検索 これを使って、他の人があなたのサイトをインターネット上で見つけます。 プレミアムドメイン名を選択 - WordPress.com のすべてのプランにはカスタムドメイン名があります。無料プレミアムドメインを登録してください。 概要 - 今日 - 全期間 - 今週の表示数 - ウィジェットを追加するには WordPress アプリにログインしてください。 - 利用可能なネットワークがありません - データを読み込めませんでした + 検索に一致する投稿はありません + WordPress.com のすべてのプランにはカスタムドメイン名があります。無料プレミアムドメインを登録してください。 + 全期間 + サイト + + ライト + ダーク + サイトを選択 種類 - サイトを選択 - ダーク - ライト - + データを読み込めませんでした + 利用可能なネットワークがありません + 今週の表示数 + ウィジェットを追加するには WordPress アプリにログインしてください。 サイトを選択 - サイト - 全期間 今週の表示数 ウィジェットを追加 プラグイン詳細の再読み込みには通常より時間がかかります。後ほどご確認ください。 @@ -1890,9 +1890,9 @@ Language: ja_JP 投稿は下書きに移動されています 投稿が復元されています 投稿を復元しました - 投稿はゴミ箱に移動中です - この投稿をゴミ箱に移動すると保存されていない変更も破棄されます。続行してもよいですか ? ローカルの変更 + この投稿をゴミ箱に移動すると保存されていない変更も破棄されます。続行してもよいですか ? + 投稿はゴミ箱に移動中です 下書きに移動 リスト表示に切り替え カード表示に切り替え @@ -1917,17 +1917,17 @@ Language: ja_JP ドメインを登録 プラグインをインストールするには、カスタムドメインをサイトに関連付ける必要があります。 プラグインをインストール - サイトのデザインは後でカスタマイズできます 公開日:%s 予約:%s 公開日時:%s 予約済み:%s 最近の週 平均表示数/日 - 表示数 期間 月と年 さらに読み込む + 表示数 + サイトのデザインは後でカスタマイズできます 今日 最高記録達成時間 最高記録達成日 @@ -1946,56 +1946,56 @@ Language: ja_JP プランを表示するにはインターネット接続が必須となるため、詳細情報が古い可能性があります。 プランを表示するにはインターネット接続が必須です。 現在、一時的にプランの読み込みができません。後ほど、もう一度お試しください。 - プランの読み込みができません + ブロックエディターを使用 接続がありません + プランの読み込みができません ブロックエディターに切り替える データの読み込み中に問題が発生しました。ページを更新してもう一度お試しください。 データは読み込まれていません ブロックエディターで新しい投稿やページを編集 - ブロックエディターを使用 終了 - 訪問者を増やす サイトをカスタマイズ 次のステップ - 独自のサイトアイコンを選択 + 訪問者を増やす 訪問者のブラウザーにアイコンが表示されます。センスのよいカスタムアイコンを追加しましょう。 - サイトのパフォーマンスを表示するには%1$s「統計情報」%2$sを選択します。 + 独自のサイトアイコンを選択 新しいアイコンをアップロードするには %1$s サイトアイコン %2$s をタップ 投稿の下書きを作成して公開してください。 + サイトのパフォーマンスを表示するには%1$s「統計情報」%2$sを選択します。 投稿のシェアを有効化 新しい投稿を自分のソーシャルメディアアカウントと自動的に共有しましょう。 + これを削除 サイト統計情報を確認 サイトのパフォーマンスを把握しましょう。 「次のステップ」を削除すると、このサイトのすべてのツアーが非表示になります。この操作を元に戻すことはできません。 次のステップを削除 - これを削除 タスクをスキップ リマインダー + 最も人気の時間 次の期間を選択 前の期間を選択 - 表示数: %1$s - 最も人気の時間 %1$s (%2$s) +%1$s (%2$s) + 表示数: %1$s サイトのプレビューの表示 クリア 接続速度が遅いようです。リストに新しいサイトが表示されない場合は、再度更新してみてください。 「Cancel Site Creation」ウィザード - 新しいサイトを作成しています 問題が発生しました サイトを作成 サイトを作成 + 新しいサイトを作成しています これが、インターネット上で他の人があなたを見つける場所です。 検索条件一致する利用可能なアドレスはありません サーバーエラーです。もう一度お試しください 問題が発生しました 問題が発生しました - サイトを作成しました。 %1$d/%2$d サイトを作成 提案が更新されました 新しく追加されたインストール型のサイトを選択できませんでした。 バージョンの競合 + サイトを作成しました。 アプリのパフォーマンス向上のため自動クラッシュレポートを許可する。 クラッシュレポート 元に戻す @@ -2004,30 +2004,24 @@ Language: ja_JP 投稿を更新 Web を破棄 ローカルを破棄 - ローカル\n%1$s\nに保存しました\nウェブ\n%2$s\nに保存しました\n この投稿には競合する2つのバージョンがあります。破棄するバージョンを選択してください。\n\n 同期の競合を解決 + ローカル\n%1$s\nに保存しました\nウェブ\n%2$s\nに保存しました\n この期間のデータがありません メディアから位置情報を削除する 現在統計を開けません。後ほど、もう一度お試しください 検索と一致するメディアがありません - GIF を検索してメディアライブラリに追加しましょう。 - 表示数 投稿者 投稿者 - 表示数 検索キーワード 検索キーワード - 表示数 タイトル 動画 - 表示数 国名 クリック数 リンク クリック数 - 表示数 リファラ リファラ 投稿とページ @@ -2041,16 +2035,20 @@ Language: ja_JP 投稿をシェア 投稿を作成 「%2$s」を公開してから%1$sが経過しました。投稿のこれまでのパフォーマンスは次のとおりです。 - 「%2$s」を公開してから%1$sが経過しました。投稿をシェアして閲覧数を増やしましょう。 + GIF を検索してメディアライブラリに追加しましょう。 + 表示数 + 表示数 + 表示数 + 表示数 + 表示数 タグとカテゴリー + 「%2$s」を公開してから%1$sが経過しました。投稿をシェアして閲覧数を増やしましょう。 全期間 %1$s - %2$s フォロワー サービス %1$s | %2$s - 表示数 タイトル - 表示数 タイトル コメント タイトル @@ -2063,6 +2061,8 @@ Language: ja_JP メール WordPress.com インサイトを管理 + 表示数 + 表示数 インサイトは追加されていません データはまだありません デバッグメニュー @@ -2093,8 +2093,8 @@ Language: ja_JP 普通 サムネイル 履歴 - 選択したページは利用できません レビュー待ち + 選択したページは利用できません ゴミ箱に移動したページはありません 予約済みページはありません ページの下書きはありません @@ -2115,7 +2115,6 @@ Language: ja_JP 検索に一致するサイトはありません 検索に一致するサイトはありません ページの親が変更されました - ページは完全に削除されました ページが予約されました ページが公開されました ページがゴミ箱に移動されました @@ -2126,16 +2125,17 @@ Language: ja_JP ページステータスを変更中に問題が発生しました ページを削除中に問題が発生しました 親の設定 + ページは完全に削除されました ここをタップ サイトの作成 - サイトを立ち上げましょう。 リストから消したいものがありますか ? + サイトを立ち上げましょう。 サイトを表示 - サイトをプレビューして訪問者に表示される内容を確認できます。 サイトを共有 + 自分のソーシャルメディアアカウントと連携すると、サイトの新しい投稿が自動的に共有されるようになります。 %1$sシェアする%2$sをタップして続行 %1$s連携%2$sをタップして、SNS アカウントを追加 - 自分のソーシャルメディアアカウントと連携すると、サイトの新しい投稿が自動的に共有されるようになります。 + サイトをプレビューして訪問者に表示される内容を確認できます。 投稿を公開 %1$s投稿の作成%2$sをタップして、新しい党呼応を作成します いいえ、結構です @@ -2143,8 +2143,8 @@ Language: ja_JP 移動 キャンセル 後で - もっと見る サイトがありません + もっと見る フォローしているトピックがありません ここでトピックを追加して、お気に入りのトピックに関する投稿を検索します Jetpack を接続するのに使用した WordPress.com アカウントにログインします。 @@ -2172,16 +2172,16 @@ Language: ja_JP 新しい「いいね」はまだついていません フォロワーはまだいません 無料プランをご利用のため、アクティビティで確認できるイベントは限られています。 - サイトに変更を加えた後、ここでアクティビティ履歴を確認できます アクティビティはまだありません + サイトに変更を加えた後、ここでアクティビティ履歴を確認できます 投稿を作成 ページを作成 メディアをアップロード メディアファイルがありません - ギャラリー サイトアイコン - テーマ画像 + ギャラリー アイキャッチ画像 + テーマ画像 削除 プロフィール写真 Transient @@ -2196,16 +2196,16 @@ Language: ja_JP %1$s %2$s に復元中です 現在サイトを復元中です サイトが正常に復元されました + 「アクティビティログ」アクションボタン サイトが正常に復元されました\n%1$s %2$s に復元されました 現在サイトを復元中です\n%1$s %2$s に復元中です - 「アクティビティログ」アクションボタン 自動管理中 この投稿を保存し、いつでも戻ってきたときに読むことができます。この端末上のみで利用でき、保存した投稿は他の端末とは同期されません。 - 投稿を保存 検索を実行できませんでした 一致する結果が見つかりません - 元の投稿を読む + 投稿を保存 サイト + 元の投稿を読む マジックリンクが送信されました コードの認証 ログイン情報 @@ -2214,13 +2214,13 @@ Language: ja_JP サイトアドレスでのログイン メールアドレスでのログイン %s をタップし、投稿をリストに保存します。 - 投稿はまだ保存されていません。 投稿を保存しました すべて表示 保存済み投稿から削除 保存済み投稿へ追加 保存済みの投稿 削除 + 投稿はまだ保存されていません。 サイトアイコンを変更 キャンセル 削除 @@ -2273,10 +2273,10 @@ Language: ja_JP 新しい投稿をメールで通知 フォロー中のすべてのサイト フォロー中のサイト - 通知付きの端末で読んでいる人 グラフとチャートを見ている人 - %2$s の %1$s この投稿を完全に削除しますか ? + 通知付きの端末で読んでいる人 + %2$s の %1$s 重要 一般 この写真を使用 @@ -2302,7 +2302,6 @@ Language: ja_JP プラグインバナー WordPress メディアから選択 カメラを開く - 端末から選択 権限グループ情報 再生 画像プレビュー @@ -2315,6 +2314,7 @@ Language: ja_JP %s を削除 %s のプロフィール写真 チェックマーク + 端末から選択 Google アカウントで登録中… Jetpack への接続に失敗しました:%s すでに Jetpack に接続しています @@ -2395,31 +2395,31 @@ Language: ja_JP \@%s サイトの作成 続行するにはタップしてください。 - サイトを作成しました。 Google が応答するのに時間がかかりすぎました。インターネット接続が安定するまで時間がかかる場合があります。 ユーザー名の変更 入力してさらに候補を表示 現在のユーザー名は %1$s%2$s%3$s です。いくつかの例外はありますが、他のユーザーには表示名 %4$s%5$s%6$s しか表示されません。 %1$s%2$s%3$s から推奨されるユーザー名はありません。候補を表示するには、さらに文字または数字を入力してください。 ユーザー名の候補の取得中にエラーが発生しました。 - ユーザー名の変更を破棄しますか ? 破棄 保存 アバターの追加 WordPress.com にすでにメールがあります。\nログインを処理しています。 + サイトを作成しました。 + ユーザー名の変更を破棄しますか ? アカウントを更新しています… メールを送信中 再試行 閉じる - メールの送信中にエラーが発生しました。今すぐ再試行するか、しばらくしてからもう一度お試しください。 ユーザー名 - 先ほど使用したようなリンクでいつでもログインできますが、ご希望の場合はパスワードを設定することもできます。 パスワード (オプション) 表示名 再試行 戻す アカウントの更新中にエラーが発生しました。変更を再試行するか、元に戻して続行できます。 アバターのアップロード中にエラーが発生しました。 + メールの送信中にエラーが発生しました。今すぐ再試行するか、しばらくしてからもう一度お試しください。 + 先ほど使用したようなリンクでいつでもログインできますが、ご希望の場合はパスワードを設定することもできます。 更新が必要 プラグインの検索 新規 @@ -2428,25 +2428,25 @@ Language: ja_JP すべて表示 管理 プラグインを検索できません - %s のインストール中にエラーが発生しました - %s をインストールしました インストール いいね 新規サイトを追加 ビジネス、マガジン、個人ブログ用の新しいサイトを作成するか、既存の WordPress インストール環境を関連付けてください。 - WordPress サイトから役立つ通知を端末で取得するには、Jetpack プラグインをインストールする必要があります。Jetpack を設定しますか ? + %s をインストールしました + %s のインストール中にエラーが発生しました 画像の遅延読み込み + WordPress サイトから役立つ通知を端末で取得するには、Jetpack プラグインをインストールする必要があります。Jetpack を設定しますか ? Jetpack をインストール テキストを切り替え お使いの WordPress バージョン 必須 WordPress バージョン 最終更新 - バージョン 5つ星 4つ星 3つ星 2つ星 1つ星 + バージョン 何も入力されていません %s回ダウンロード %s評価 @@ -2462,21 +2462,21 @@ Language: ja_JP 作成者: %s 写真を変更 プラグインを読み込めませんでした - ページ サイトのタグを管理 保存中 削除中 「%s」タグを永久に削除しますか ? + ページ この名前のタグは既に存在します - 新規タグを追加 - 説明 タグ + 説明 + 新規タグを追加 この WordPress.comサイトでは、Google が主導しているモバイル端末の読み込み時間を大幅に短縮するイニシアチブである Accelerated Mobile Pages の使用をサポートしています Accelerated Mobile Pages (AMP) - タイムゾーンを読み込めませんでした 日付と時刻の書式の詳細 - カスタム形式 + タイムゾーンを読み込めませんでした カスタム + カスタム形式 ページ毎の投稿数 お住いのタイムゾーン内の都市を選択 タイムゾーン @@ -2548,8 +2548,8 @@ Language: ja_JP コンテンツを共有する WordPress サイトのアドレスを入力します。 サイトの接続解除中のエラー サイトが接続解除されました - 連携解除 このサイトから Jetpack の接続を解除してもよいですか ? + 連携解除 「WordPress.com との連携を解除」 単一または一連の IP アドレスをホワイトリストに追加すると、それらが Jetpack にブロックされなくなります。IPv4と IPv6を使用できます。範囲を指定するには、下限値と上限値をダッシュで区切って入力します。例: 12.12.12.1–12.12.12.100 二段階認証が必要 @@ -2585,24 +2585,24 @@ Language: ja_JP ファイル名 URL 代替テキスト - サイトと連携 点滅 + サイトと連携 端末をバイブレート 音声を選択する 視覚効果と音声 WordPress.com からのメール 保留の下書きを通知する 他サイト上のコメント - その他 自分の全サイト + その他 あなたのサイト 通知設定をオフにすると、通知の種類に関係なく、このアプリからの通知がすべて無効になります。通知設定をオンにした後で、受信する通知の種類を調整できます。 この端末で通知を受信するには、通知設定を有効化してください。 通知を有効化 通知を無効化 オフ - オン 最大動画サイズ + オン 最大画像サイズ 投稿内のメディアのアップロード中にエラーが発生しました: %s。 投稿のアップロード中にエラーが発生しました: %s。 @@ -2642,8 +2642,8 @@ Language: ja_JP 連携する WordPress サイトのアドレスを入力してください。 すでに WordPress.com にログインしています 次へ - 別のサイトと連携 WordPress.com パスワードを入力してください。 + 別のサイトと連携 ログインメールのリクエスト このパスワードは間違っているようです。入力した情報をもう一度確認してから、やり直してください。 SMS 経由で認証コードをリクエスト。 @@ -2655,9 +2655,9 @@ Language: ja_JP 画像の最適化により、画像サイズを縮小して迅速に読み込めます。\n\nこれはサイト設定でいつでも変更できます。 画像の最適化を有効にしますか ? 無効のままにする - 有効化する プロフィール写真 サーバーから予期しない応答が返されました + 有効化する 読み込みはすでに完了しているため、停止することはできません タイトル やり直し @@ -2688,8 +2688,8 @@ Language: ja_JP トップレベル 親カテゴリー (オプション): 音声ファイルがありません - 文書がありません 動画がありません + 文書がありません 画像がありません サービスが応答するのに時間がかかりすぎました ファイルが大きすぎてこのサイトにアップロードできません @@ -2704,8 +2704,8 @@ Language: ja_JP %1$sは写真へのアクセスを拒否されました。これを解決するには、権限を編集して、%2$sをオンにしてください。 コメントを表示 動画の画質。値が高いほど、画質が良いことを意味します。 - 投稿の動画をこのサイズにする サイズ変更と動画圧縮を可能にするには有効化してください + 投稿の動画をこのサイズにする ビデオを最適化 下書きをアップロードしました 動画の画質 @@ -2718,8 +2718,8 @@ Language: ja_JP 共有ボタンのラベルテキストを変更します。このテキストを表示するには、少なくとも1つの共有ボタンを追加する必要があります。 連携済みアカウント アカウントが選択されていなかったため、%s の連携を確立できませんでした。 - 連携済み Twitter + 連携済み いいね すべてのコメントに対して自分や他の読者が「いいね」の評価を付けられるようにする ボタン @@ -2728,8 +2728,8 @@ Language: ja_JP 投稿の下に表示されているボタンを選択してください Twitter ユーザー名 コメントへのいいね - ボタンスタイル ラベル + ボタンスタイル 共有ボタン 「いいね」ボタン表示 リブログボタンを表示 @@ -2739,9 +2739,9 @@ Language: ja_JP アイコンのみ アイコンとテキスト 認証するアカウントを選択してください。投稿は、選択されたアカウントに自動で共有されることに注意してください。 - %s を連携中 %s との連携を解除しますか ? 別のアカウントを連携 + %s を連携中 再連携 切断 連携 @@ -2793,17 +2793,17 @@ Language: ja_JP 投稿をオンラインで保存しました 写真の画質。値が高いほど、画質が良いことを意味します。 写真をリサイズして圧縮できます - 最高 非常に高い 高い 普通 低い アップロード済み - アップロード失敗 + 最高 削除済み 削除中 アップロード中 待機中 + アップロード失敗 画質 不明なエラーにより、メディアのアップロードはすべてキャンセルされました。もう一度アップロードをお試しください 投稿フォーマットが不明です @@ -2849,8 +2849,8 @@ Language: ja_JP 「いいね」を付けています… 処理中… 操作が完了しました。 - 「いいね」を付けたコメント ログアウト + 「いいね」を付けたコメント WordPress.com にログインする WordPress.com の詳細 関連 (%s) @@ -2863,16 +2863,16 @@ Language: ja_JP コメントを承認しました。 いいね - 閲覧者 フォロワー + 閲覧者 接続されていないためプロフィールを保存できませんでした - - なし + + %1$d が選択されています サイトのユーザーを取得できませんでした - メールフォロワー フォロワー + メールフォロワー ユーザーを取得中… 閲覧者 メールフォロワー @@ -2887,23 +2887,23 @@ Language: ja_JP サイトのメールフォロワーを取得できませんでした サイトのフォロワーを取得できませんでした 一部のメディアのアップロードに失敗しました。この状態では、HTML モードに切り替えることは\nできません。失敗したアップロードをすべて削除して続行しますか ? - 画像サムネイル ビジュアルエディター - - リンク先 - Alt テキスト + 画像サムネイル 見出し + Alt テキスト + 変更を保存しました + リンク先 保存されていない変更を破棄しますか ? アップロードを中止しますか ? メディアの挿入中にエラーが発生しました メディアをアップロードしています。完了するまで、しばらくお待ちください。 HTML モードでは直接メディアを挿入できません。ビジュアルモードに戻してください。 ギャラリーをアップロードしています… - タップしてもう一度お試しください。 + 招待メールを送信しましたが、エラーが発生しました。 招待メールを送信しました + タップしてもう一度お試しください。 %1$s: %2$s - 招待メールを送信しましたが、エラーが発生しました。 招待メールの送信中にエラーが発生しました。 送信できません。無効なユーザー名またはメールアドレスがあります 送信できません。ユーザー名またはメールアドレスが無効です @@ -2911,8 +2911,8 @@ Language: ja_JP カスタムメッセージ 招待 ユーザー名またはメールアドレス - 他の人を招待 外部 + 他の人を招待 検索履歴の削除 検索履歴を削除しますか ? お使いの言語で「%s」についての投稿は見つかりませんでした @@ -2920,33 +2920,33 @@ Language: ja_JP 関連記事 プレビュー画面ではリンクが無効になっています 送信 - %1$s を削除しました %1$s を削除すると、そのユーザーはこのサイトにアクセスできなくなりますが、%1$s によって作成されたコンテンツはサイト上に残ります。\n\n本当にこのユーザーを削除しますか ? + %1$s を削除しました %1$s を削除 - 権限グループ + 権限グループ このリスト内のサイトには最近の投稿がありません ユーザーを削除できませんでした ユーザー権限グループを更新できませんでした サイト閲覧者を取得できませんでした Gravatar 更新エラー - Gravatar 再読み込みエラー 切り抜き済み画像位置不明エラー + Gravatar 再読み込みエラー 画像切り抜きエラー メールをチェック 現在ご利用いただけません。パスワードを入力してください ログインしています コメントする際に公開表示されます。 写真を撮影または選択 - プラン プラン + プラン 投稿、ページ、設定については、%s 宛てにメールで送信されます。 コンテンツをエクスポート - エクスポートメールを送信しました。 コンテンツをエクスポート中… - 購入を確認中 - 購入を表示 + エクスポートメールを送信しました。 サイトには有効なプレミアムアップグレードがあります。サイトを削除する前に、アップグレードをキャンセルしてください。 + 購入を表示 + 購入を確認中 プレミアムアップグレード エラーが発生しました。購入をリクエストできませんでした。 サイトを削除中… @@ -2960,10 +2960,10 @@ Language: ja_JP サイト削除を確認 サポートに問い合わせる サイトは維持したままで現在の投稿やページを削除したい場合は、サポートスタッフが投稿、ページ、メディア、コメントをすべて削除するお手伝いをさせていただきます。\n\nこうすることで、サイトと URL を保ったまま新しいコンテンツを一から作り始めることができます。サポートに連絡し、現在のコンテンツをすべて削除したい旨をお知らせください。 - お手伝いさせてください サイトを最初からやり直す - 最初からやり直す + お手伝いさせてください アプリ設定 + 最初からやり直す アップロードに失敗したメディアを削除 高度な設定 ゴミ箱内にコメントはありません @@ -2971,34 +2971,34 @@ Language: ja_JP 承認済みのコメントはありません スキップ 接続できませんでした。必要な XML-RPC メソッドがサーバーにありません。 - 中央 - 動画 ステータス - 標準 - 引用 - リンク - 画像 - ギャラリー + 動画 + 中央 チャット - 音声 - アサイド + ギャラリー + 画像 + リンク + 引用 + 標準 WordPress.com のコースやイベント (オンライン・オフライン) の情報。 + アサイド + 音声 WordPress.com の研究・調査に参加する機会。 WordPress.com を最大限に活用するためのヒント。 コミュニティ - リサーチ - 提案 自分のコメントへの返信 - ユーザー名メンション + 提案 + リサーチ サイトの達成記録 - サイトでフォロー + ユーザー名メンション 自分の投稿への「いいね」 + サイトでフォロー 自分のコメントへの「いいね」 サイト上のコメント %d項目 1項目 - すべてのユーザー 既知のユーザーのコメント + すべてのユーザー コメントなし %d件のコメント (1ページあたり) 1件のコメント (1ページあたり) @@ -3008,10 +3008,10 @@ Language: ja_JP すべてのコメントを自動的に承認します。 ユーザーのコメントが以前に承認されている場合、自動的に承認します すべてのコメントで手動の承認が必要です。 - %d日 1日 - ウェブアドレス + %d日 基本のサイト + ウェブアドレス %1$s へ送信されたメール内の認証リンクをクリックして、新しいアドレスを承認してください メディアをアップロードしています。完了するまで、しばらくお待ちください。 現在、コメントを更新することができないため、古いコメントが表示されます @@ -3021,13 +3021,13 @@ Language: ja_JP これらのコメントを完全に削除しますか ? このコメントを完全に削除しますか ? 削除 - 復元 コメントを削除しました + 復元 スパムコメントはありません - すべて ページを読み込めません - オフ + すべて 管理画面の言語 + オフ このアプリについて アカウント設定を保存できませんでした アカウント設定を読み込めませんでした @@ -3035,9 +3035,9 @@ Language: ja_JP 言語コードを認識できません コメントスレッドでの入れ子化を許可する。 入れ子数の上限 - 無効 - 検索 削除 + 検索 + 無効 元のサイズ サイトはあなたと、承認したユーザーのみが表示できます 誰でもサイトを閲覧することができますが、検索エンジンにはインデックスしないよう要求します @@ -3046,9 +3046,9 @@ Language: ja_JP 自己紹介 表示名が設定されていない場合、デフォルトでユーザー名が指定されます 公開表示名 - - プロフィール + + 関連記事のプレビュー画像 サイト情報を保存できませんでした サイト情報を取得できませんでした @@ -3103,8 +3103,8 @@ Language: ja_JP %d階層 プライベート 非表示 - 一般公開 サイトを削除 + 一般公開 承認待ち コメント内のリンク 自動承認 @@ -3119,22 +3119,22 @@ Language: ja_JP デフォルトのフォーマット デフォルトカテゴリー アドレス - キャッチフレーズ サイトのタイトル + キャッチフレーズ 新しい投稿のデフォルト - 投稿設定 アカウント + 投稿設定 一般 新しいものから表示 + ディスカッション + プライバシー + 関連記事 + コメント 古いものから表示 この日付に閉じる: - コメント - 関連記事 - プライバシー - ディスカッション このサイトにメディアをアップロードする権限がありません - 不明 なし + 不明 この投稿は存在しません この投稿を表示する権限がありません この投稿を取得できません @@ -3146,22 +3146,22 @@ Language: ja_JP 何か問題が発生しました。テーマを有効化できません by %1$s %1$s を選んでいただきありがとうございます - サイト管理 - 完了 - サポート - 詳細 - 表示 お試し & カスタマイズ + 表示 + 詳細 + サポート + 完了 + サイト管理 有効化 - 有効 - サポート - 詳細 - カスタマイズ 現在のテーマ - ページを更新しました - 投稿を更新しました - ページを公開しました + カスタマイズ + 詳細 + サポート + 有効 投稿を公開しました + ページを公開しました + 投稿を更新しました + ページを更新しました テーマが見つかりませんでした。 さらに投稿を読み込む 「%s」に一致するサイトはありません @@ -3194,277 +3194,277 @@ Language: ja_JP 通知設定を読み込めませんでした コメントへの「いいね」 アプリ通知 - メール 「通知」タブ + メール アカウントに関する重要なお知らせは常にメールでお送りしますが、役に立つ追加情報を受け取ることもできます。 最新の投稿概要 接続できません 投稿をゴミ箱へ移動しました - ゴミ箱 統計情報 + ゴミ箱 プレビュー 表示 - 公開 編集 + 公開 このサイトにアクセスする権限がありません サイトが見つかりませんでした 元に戻す リクエストの有効期限が切れています。もう一度試すには WordPress.com にログインしてください。 - 無視 過去最高の表示数 + 無視 今日の統計情報 全期間の投稿、表示数、訪問者 まとめ WordPress.com からログアウト - WordPress.com にログイン ログイン/ログアウト + WordPress.com にログイン アカウント設定 現在のサイトのため “%s” は非表示になりませんでした WordPress.com サイトを作成 インストール型サイトを追加 - 新規サイトを追加 サイトを表示/非表示 - サイトを選択 - サイトを表示 + 新規サイトを追加 管理画面表示 + サイトを表示 + サイトを選択 サイト切り替え - サイト設定 - 投稿 公開 外観 + サイト設定 + 投稿 設定 タップして表示 すべて選択解除 - すべて選択 - 隠す 表示 - 続けるにはログインしてください。 - 無効な認証コード - 認証コード + 隠す + すべて選択 言語 + 認証コード + 無効な認証コード + 続けるにはログインしてください。 投稿を取得できません 通知を開けませんでした 不明な検索語 - 検索キーワード - 投稿者 - ページを取得中… 投稿を取得中… メディアを取得中… + ページを取得中… + 検索キーワード + 投稿者 アプリケーションログをクリップボードにコピーしました - このサイトは空です 新規投稿 テキストをクリップボードにコピーする際にエラーが発生しました 投稿をアップロード中 - %1$d年 - 1年 + このサイトは空です + テーマを取得中… %1$dヶ月 + 1年 + %1$d年 1ヶ月 - %1$d日 - 1日 - %1$d時間 - 1時間前 %1$d分 + 1時間前 + %1$d時間 + 1日 + %1$d日 1分前 数秒前 - フォロワー 動画 - 投稿とページ + フォロワー いいね - サイト訪問者 - 表示数 - テーマを取得中… + 表示数 + サイト訪問者 + 投稿とページ 詳細 %d件選択 よく聞かれる質問を表示 コメントはまだありません - このトピックには投稿がありません - いいね 元の記事を表示 - コメントは受け付けていません + いいね %1$d/%2$d - 空の投稿は公開できません - 投稿の表示/編集権限がありません - ページの表示/編集権限がありません 続き - 1ヶ月以上前 - 1週間以上前 - 2日以上前 - ヘルプ & サポート 「いいね」済み コメント ゴミ箱に入れたコメント - %s への返信 投稿はまだありません。新規作成してください。 + %s への返信 ログアウト中… + 1ヶ月以上前 + 2日以上前 + 1週間以上前 + ページの表示/編集権限がありません + 投稿の表示/編集権限がありません + コメントは受け付けていません + このトピックには投稿がありません + 空の投稿は公開できません + ヘルプ & サポート 操作を実行できませんでした - サイトをブロックできませんでした このサイトからの投稿は今後表示されません このサイトをブロック - 予約 + サイトをブロックできませんでした 更新 - おすすめサイトはありません + 予約 + フォロー中のサイト このサイトをフォローできませんでした - このサイトをフォローできません このサイトをすでにフォローしています - このサイトを表示できません サイトをフォローしました - フォローする URL またはトピックを入力 - フォロー中のサイト - フォローしているトピック + このサイトをフォローできません + おすすめサイトはありません Reader サイト - 通常問題なくサイトに接続できる場合、このエラーは誰かがあなたのサイトになりすましていることを意味しているかもしれないので、そのまま進むべきではありません。それでもこの証明書を信頼してもよいですか ? - 無効な SSL 証明書 + このサイトを表示できません + フォローしているトピック + フォローする URL またはトピックを入力 ヘルプ - 入力されたユーザー名またはパスワードが間違っています - 有効なメールアドレスを入力してください - 無効なメールアドレスです + 無効な SSL 証明書 + 通常問題なくサイトに接続できる場合、このエラーは誰かがあなたのサイトになりすましていることを意味しているかもしれないので、そのまま進むべきではありません。それでもこの証明書を信頼してもよいですか ? 画像ダウンロードエラー - コメントを読み込めませんでした + このブログにアクセスする際にエラーが発生しました + スパムはありません + 利用可能なネットワークがありません + テーマの取得に失敗しました + カテゴリーの追加に失敗しました + カテゴリーを追加しました + カテゴリー名は必須項目です + 有効なメールアドレスを入力してください コメント編集の際にエラーが発生しました - 承認の際にエラーが発生しました エラーが発生しました - コメントを再読み込みできませんでした - ページを再読み込みできませんでした - 投稿を再読み込みできませんでした - 投稿を削除する際にエラーが発生しました + コメントを読み込めませんでした + 承認の際にエラーが発生しました + 無効なメールアドレスです 通知がありません メディアをアップロードするには SD カードが必要です - カテゴリー名は必須項目です - カテゴリーを追加しました - カテゴリーの追加に失敗しました - スパムはありません - テーマの取得に失敗しました - このブログにアクセスする際にエラーが発生しました + 入力されたユーザー名またはパスワードが間違っています + 投稿を再読み込みできませんでした + ページを再読み込みできませんでした + コメントを再読み込みできませんでした + 投稿を削除する際にエラーが発生しました メディア項目を読み込めませんでした - 利用可能なネットワークがありません - このトピックを削除できません - このトピックを追加できません - アプリケーションログ - アプリのデータベースを作成する際にエラーが発生しました。アプリをもう一度インストールしてみてください。 - このブログは非表示になっており読み込めません。設定画面から再有効化してもう一度お試しください。 - メディアファイルを再読み込みできませんでした - WordPress ブログ 画像設定 ローカルの変更 新規メディア - 新規投稿 - 通知はまだありません。 - 認証が必要です - 入力したサイト URL が正しいか確認してください - メディアアップロードの際に一時ファイルを作成できませんでした。端末上に空き容量があるか確認してください。 - カテゴリー名 新規カテゴリーを追加 - ブラウザで表示 - サイトを削除 - コメントが変更されていません + 編集をキャンセル + カテゴリー名 + 承認済み + スパム + ゴミ箱移動済み + 承認待ち + 接続エラー コメント欄は必須項目です - このコメントの修正を中止しますか ? - 変更を保存中 - ゴミ箱 + リンクを作成 ゴミ箱に移動しますか ? - ゴミ箱 - スパム - 承認を解除 - 承認 コメント編集 - ゴミ箱移動済み - スパム - 承認待ち - 承認済み - 固定ページを削除しますか ? - 投稿を削除しますか ? - 投稿設定 - アップロードするメディアファイルが見つかりませんでした。削除または移動されたのかもしれません。 横配置 - ローカルの下書き - ページ設定 - リンクを作成 + 認証が必要です + さらに詳しく リンク​​テキスト (オプション) - 一部のメディアは現在削除できません。後ほどもう一度お試しください。 - メディアライブラリを表示する権限がありません + ローカルの下書き サムネイルグリッド - さらに詳しく + 承認 + スパム + ゴミ箱 + 承認を解除 + 新規投稿 + ページ設定 + 投稿設定 + アプリケーションログ + 変更を保存中 + カテゴリーを選択 + このコメントの修正を中止しますか ? + コメントが変更されていません + ゴミ箱 + ブラウザで表示 + WordPress ブログ + アプリのデータベースを作成する際にエラーが発生しました。アプリをもう一度インストールしてみてください。 投稿を読み込む際にエラーが発生しました。再読み込みしてもう一度お試しください。 + メディアライブラリを表示する権限がありません + 一部のメディアは現在削除できません。後ほどもう一度お試しください。 + このブログは非表示になっており読み込めません。設定画面から再有効化してもう一度お試しください。 + サイトを削除 + 通知はまだありません。 + 入力したサイト URL が正しいか確認してください + メディアアップロードの際に一時ファイルを作成できませんでした。端末上に空き容量があるか確認してください。 + メディアファイルを再読み込みできませんでした + アップロードするメディアファイルが見つかりませんでした。削除または移動されたのかもしれません。 + 固定ページを削除しますか ? + 投稿を削除しますか ? プラグインへのアクセス中にエラーが発生しました - 編集をキャンセル - 接続エラー - カテゴリーを選択 + このトピックを追加できません + このトピックを削除できません リンクを共有 投稿を取得中… - あなたと%,d人が「いいね」しました - %,d 人が「いいね」しています - 公開ブログがないため WordPress で共有できません コメントをスパムとしてマークしました コメントの承認を解除しました + 公開ブログがないため WordPress で共有できません + %,d 人が「いいね」しています + あなたと%,d人が「いいね」しました + 画像を選択 + 動画を選択 この投稿を読み込みできません あなたと他1人が「いいね」をつけました - 動画を選択 - 画像を選択 - 登録 - %sを開けませんでした + リストが空です + (無題) + リブログ + 共有 + フォロー + フォロー中 + %s を追加 + %s を削除 + 「いいね」をつけました 画像を表示できません 共有に失敗しました - 有効なトピックではありません - このトピックをすでにフォローしています - コメントを投稿できませんでした - 「いいね」をつけました + %sを開けませんでした 1人がいいねをつけました - %s を削除 - %s を追加 + コメントを投稿できませんでした コメントに返信… - フォロー中 - フォロー - 共有 - リブログ - (無題) コメントはまだありません - リストが空です - - - - 昨日 + 登録 + このトピックをすでにフォローしています + 有効なトピックではありません + テーマ + 正方形タイル + タイルモザイク + 丸型 + スライドショー + タイトル + キャプション + 説明 + 有効化 + 共有 + 統計 + クリック数 今日 + 昨日 + + + リファラ - タグとカテゴリー - クリック数 - 統計 - 共有 - 有効化 更新に失敗しました - 説明 - キャプション - タイトル - スライドショー - 丸型 - タイルモザイク - 正方形タイル - テーマ - 保存しない + タグとカテゴリー 管理 + 保存しない + ログイン + 返信を公開しました + フォロー あと%d件。 %d件の新しい通知 - フォロー - 返信を公開しました - ログイン 読込中… - HTTP パスワード HTTP ユーザー名 + HTTP パスワード メディアをアップロードする際にエラーが発生しました ユーザー名またはパスワードが正しくありません。 - ログイン - ユーザー名 パスワード + ユーザー名 + ログイン 購読ブログ - 投稿本文中に画像を含める アイキャッチ画像として使用 - 横幅 - キャプション (オプション) + 投稿本文中に画像を含める + 利用可能なネットワークがありません ページ + キャプション (オプション) + 横幅 投稿 匿名 - 利用可能なネットワークがありません 完了 OK URL @@ -3479,27 +3479,27 @@ Language: ja_JP ショートカット名を記入してください 非公開 タイトル - タグはコンマで区切ってください カテゴリー + タグはコンマで区切ってください SD カードが必要です メディア カテゴリーを更新しました - 承認 削除 - カテゴリーの更新に失敗しました + 承認 なし - 今すぐ公開 + カテゴリーの更新に失敗しました 返信する - オン プレビュー - カテゴリーの再読み込みエラー - エラー - いいえ + オン + キャンセル + 保存 + 追加 はい + いいえ + エラー + カテゴリーの再読み込みエラー 通知設定 - 追加 - 保存 - キャンセル + 今すぐ公開 1回 2回 diff --git a/WordPress/src/main/res/values-lv/strings.xml b/WordPress/src/main/res/values-lv/strings.xml index 2e63d7abad00..0fc52dfe2f3e 100644 --- a/WordPress/src/main/res/values-lv/strings.xml +++ b/WordPress/src/main/res/values-lv/strings.xml @@ -1,11 +1,38 @@ + <b>%1$s</b> izmanto %2$s atsevišķus Jetpack spraudņus + <b>%1$s</b> izmanto spraudni <b>%2$s</b> + WordPress lietotne neatbalsta vietnes ar atsevišķiem Jetpack spraudņiem. + <b>%1$s</b> izmanto atsevišķus Jetpack spraudņus, kurus neatbalsta WordPress lietotne. + <b>%1$s</b> izmanto spraudni <b>%2$s</b>, ko neatbalsta WordPress lietotne. + Nevar piekļūt dažām jūsu vietnēm + Nevar piekļūt vienai no jūsu vietnēm + Lūdzu, pārslēdzieties uz lietotni Jetpack, kur mēs jums palīdzēsim pievienot visu Jetpack spraudni, lai izmantotu šo vietni ar lietotni. + Pārslēdzieties uz Jetpack lietotni + %1$s izmanto %2$s, kas vēl neatbalsta visas lietotnes funkcijas. Lūdzu, instalējiet %3$s, lai izmantotu lietotni šajā vietnē. + Šī vietne + %1$s izmanto %2$s, kas vēl neatbalsta visas lietotnes funkcijas. Lūdzu, instalējiet %3$s. + %1$s izmanto %2$s, kas vēl neatbalsta visas lietotnes funkcijas. Lūdzu, instalējiet %3$s. + Pāreja uz Jetpack lietotni pēc dažām dienām. + Pārslēgšanās ir bezmaksas un aizņem tikai minūti. + Statistika, lasītājs, paziņojumi un citas Jetpack darbināmas funkcijas ir noņemtas no WordPress lietotnes, un tagad tās var atrast tikai Jetpack lietotnē. + Uzziniet vairāk vietnē Jetpack.com + Pārslēdzieties uz Jetpack lietotni + %s ir pārcēlušies uz Jetpack lietotni. + %s ir pārcēlies uz Jetpack lietotni. + WP administrators + Pārvaldīt + Satiksme + Saturs + Uzstādīt + Gatavs + Tagad, kad Jetpack ir instalēts, mums ir tikai jāveic iestatīšana. Tas prasīs tikai minūti. Izgaismojiet šo ziņu tūlīt Izgaismojiet šo lapu Izgaismojiet šo ziņu @@ -38,9 +65,24 @@ Language: lv pilns Jetpack spraudnis atsevišķi Jetpack spraudņi spraudnis %1$s + %1$s izmanto %2$s, kas vēl neatbalsta visas lietotnes funkcijas. Lūdzu, instalējiet %3$s, lai izmantotu lietotni šajā vietnē. Lūdzu, instalējiet pilno Jetpack spraudņa versiju Ir pieejama tikai viena vietne, tāpēc jūs nevarat mainīt savu galveno vietni. + Sazinieties ar atbalsta dienestu + Mēģiniet vēlreiz + Jetpack pašlaik nevarēja instalēt. + Radās problēma + Kļūdas ikona + Gatavs šīs vietnes izmantošanai ar lietotni. + Instalēts Jetpack + Jetpack instalēšana jūsu vietnē. Tas var ilgt dažas minūtes. + Jetpack instalēšana + Turpināt + Jūsu vietnes akreditācijas dati netiks saglabāti un tiek izmantoti tikai Jetpack instalēšanai. + Instalēt Jetpack + Jetpack ikona Reklamējiet ar Blaze + Atbrīvojiet visu savas vietnes potenciālu. Iegūstiet statistiku, paziņojumus un daudz ko citu, izmantojot Jetpack. Jūsu vietnei ir spraudnis Jetpack Jetpack mobilā lietotne ir paredzēta darbam kopā ar Jetpack spraudni. Pārslēdziet tagad, lai piekļūtu statistikai, paziņojumiem, lasītājam un daudz kam citam. Saņemiet paziņojumus par jauniem komentāriem, atzīmēm Patīk, skatījumiem un daudz ko citu. diff --git a/WordPress/src/main/res/values-sk/strings.xml b/WordPress/src/main/res/values-sk/strings.xml index 0a4001c34f95..1a4e535e6587 100644 --- a/WordPress/src/main/res/values-sk/strings.xml +++ b/WordPress/src/main/res/values-sk/strings.xml @@ -1,6 +1,6 @@ diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSourceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSourceTest.kt index 75041e3e6630..966cd1fa3ddf 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSourceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsSourceTest.kt @@ -11,6 +11,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.model.activity.ActivityLogModel import org.wordpress.android.fluxc.model.dashboard.CardModel import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel.PostCardModel @@ -22,8 +23,10 @@ import org.wordpress.android.fluxc.store.dashboard.CardsStore import org.wordpress.android.fluxc.store.dashboard.CardsStore.CardsError import org.wordpress.android.fluxc.store.dashboard.CardsStore.CardsErrorType import org.wordpress.android.fluxc.store.dashboard.CardsStore.CardsResult +import org.wordpress.android.fluxc.tools.FormattableContent import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.util.config.DashboardCardActivityLogConfig import org.wordpress.android.util.config.DashboardCardPagesConfig import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig @@ -54,6 +57,23 @@ const val PAGE_MODIFIED_ON = "2023-03-02 10:26:53" const val PAGE_STATUS = "publish" const val PAGE_DATE = "2023-03-02 10:30:53" +/* ACTIVITY */ +const val ACTIVITY_ID = "activity123" +const val ACTIVITY_SUMMARY = "activity" +const val ACTIVITY_NAME = "name" +const val ACTIVITY_TYPE = "create a blog" +const val ACTIVITY_IS_REWINDABLE = false +const val ACTIVITY_REWIND_ID = "10.0" +const val ACTIVITY_GRID_ICON = "gridicon.jpg" +const val ACTIVITY_STATUS = "OK" +const val ACTIVITY_ACTOR_TYPE = "author" +const val ACTIVITY_ACTOR_NAME = "John Smith" +const val ACTIVITY_ACTOR_WPCOM_USER_ID = 15L +const val ACTIVITY_ACTOR_ROLE = "admin" +const val ACTIVITY_ACTOR_ICON_URL = "dog.jpg" +const val ACTIVITY_PUBLISHED_DATE = "2021-12-27 11:33:55" +const val ACTIVITY_CONTENT = "content" + /* MODEL */ private val TODAYS_STATS_CARDS_MODEL = TodaysStatsCardModel( @@ -90,15 +110,41 @@ private val PAGES_MODEL = PagesCardModel( pages = listOf(PAGE_MODEL) ) +private val ACTIVITY_LOG_MODEL = ActivityLogModel( + summary = ACTIVITY_SUMMARY, + content = FormattableContent(text = ACTIVITY_CONTENT), + name = ACTIVITY_NAME, + actor = ActivityLogModel.ActivityActor( + displayName = ACTIVITY_ACTOR_NAME, + type = ACTIVITY_ACTOR_TYPE, + wpcomUserID = ACTIVITY_ACTOR_WPCOM_USER_ID, + avatarURL = ACTIVITY_ACTOR_ICON_URL, + role = ACTIVITY_ACTOR_ROLE, + ), + type = ACTIVITY_TYPE, + published = CardsUtils.fromDate(ACTIVITY_PUBLISHED_DATE), + rewindable = ACTIVITY_IS_REWINDABLE, + rewindID = ACTIVITY_REWIND_ID, + gridicon = ACTIVITY_GRID_ICON, + status = ACTIVITY_STATUS, + activityID = ACTIVITY_ID +) + +private val ACTIVITY_CARD_MODEL = CardModel.ActivityCardModel( + activities = listOf(ACTIVITY_LOG_MODEL) +) + private val CARDS_MODEL: List = listOf( TODAYS_STATS_CARDS_MODEL, POSTS_MODEL, - PAGES_MODEL + PAGES_MODEL, + ACTIVITY_CARD_MODEL ) private val DEFAULT_CARD_TYPE = listOf(CardModel.Type.POSTS) private val STATS_FEATURED_ENABLED_CARD_TYPES = listOf(CardModel.Type.TODAYS_STATS, CardModel.Type.POSTS) private val PAGES_FEATURED_ENABLED_CARD_TYPE = listOf(CardModel.Type.PAGES, CardModel.Type.POSTS) +private val ACTIVITY_FEATURED_ENABLED_CARD_TYPE = listOf(CardModel.Type.ACTIVITY, CardModel.Type.POSTS) @ExperimentalCoroutinesApi class CardsSourceTest : BaseUnitTest() { @@ -117,6 +163,9 @@ class CardsSourceTest : BaseUnitTest() { @Mock private lateinit var dashboardCardPagesConfig: DashboardCardPagesConfig + @Mock + private lateinit var dashboardCardActivityLogConfig: DashboardCardActivityLogConfig + private lateinit var cardSource: CardsSource private val data = CardsResult( @@ -134,24 +183,32 @@ class CardsSourceTest : BaseUnitTest() { private fun init( isTodaysStatsCardFeatureConfigEnabled: Boolean = false, - isDashboardCardPagesConfigEnabled: Boolean = false + isDashboardCardPagesConfigEnabled: Boolean = false, + isDashboardCardActivityLogConfigEnabled: Boolean = false ) { - setUpMocks(isTodaysStatsCardFeatureConfigEnabled, isDashboardCardPagesConfigEnabled) + setUpMocks( + isTodaysStatsCardFeatureConfigEnabled, + isDashboardCardPagesConfigEnabled, + isDashboardCardActivityLogConfigEnabled + ) cardSource = CardsSource( selectedSiteRepository, cardsStore, todaysStatsCardFeatureConfig, dashboardCardPagesConfig, + dashboardCardActivityLogConfig, testDispatcher() ) } private fun setUpMocks( isTodaysStatsCardFeatureConfigEnabled: Boolean, - isDashboardCardPagesConfigEnabled: Boolean = false + isDashboardCardPagesConfigEnabled: Boolean = false, + isDashboardCardActivityLogConfig: Boolean = false ) { whenever(todaysStatsCardFeatureConfig.isEnabled()).thenReturn(isTodaysStatsCardFeatureConfigEnabled) whenever(dashboardCardPagesConfig.isEnabled()).thenReturn(isDashboardCardPagesConfigEnabled) + whenever(dashboardCardActivityLogConfig.isEnabled()).thenReturn(isDashboardCardActivityLogConfig) whenever(siteModel.id).thenReturn(SITE_LOCAL_ID) whenever(selectedSiteRepository.getSelectedSite()).thenReturn(siteModel) } @@ -440,4 +497,34 @@ class CardsSourceTest : BaseUnitTest() { verify(cardsStore).fetchCards(siteModel, PAGES_FEATURED_ENABLED_CARD_TYPE) } + + @Test + fun `given activity feature enabled, when build is invoked, then activity from store(database)`() = test { + init(isDashboardCardActivityLogConfigEnabled = true) + val result = mutableListOf() + whenever(cardsStore.getCards(siteModel, ACTIVITY_FEATURED_ENABLED_CARD_TYPE)).thenReturn(flowOf(data)) + + cardSource.build(testScope(), SITE_LOCAL_ID).observeForever { + it?.let { result.add(it) } + } + + verify(cardsStore).getCards(siteModel, ACTIVITY_FEATURED_ENABLED_CARD_TYPE) + } + + @Test + fun `given activity feature enabled, when refresh is invoked, then activity are requested from network`() = + test { + init(isDashboardCardActivityLogConfigEnabled = true) + val result = mutableListOf() + whenever(cardsStore.getCards(siteModel, ACTIVITY_FEATURED_ENABLED_CARD_TYPE)).thenReturn(flowOf(data)) + whenever(cardsStore.fetchCards(siteModel, ACTIVITY_FEATURED_ENABLED_CARD_TYPE)).thenReturn(success) + cardSource.refresh.observeForever { } + + cardSource.build(testScope(), SITE_LOCAL_ID).observeForever { + it?.let { result.add(it) } + } + advanceUntilIdle() + + verify(cardsStore).fetchCards(siteModel, ACTIVITY_FEATURED_ENABLED_CARD_TYPE) + } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt new file mode 100644 index 000000000000..f8efb2efdccd --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt @@ -0,0 +1,55 @@ +package org.wordpress.android.ui.sitecreation + +import org.mockito.kotlin.mock +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.network.rest.wpcom.transactions.TransactionsRestClient.CreateShoppingCartResponse +import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged +import org.wordpress.android.fluxc.store.SiteStore.SiteError +import org.wordpress.android.fluxc.store.SiteStore.SiteErrorType.GENERIC_ERROR +import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartError +import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartCreated +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewActivity +import org.wordpress.android.ui.domains.DomainRegistrationCompletedEvent +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Completed +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched +import org.wordpress.android.ui.sitecreation.domains.DomainModel +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.CREATE_SITE +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.FAILURE +import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.SUCCESS +import org.wordpress.android.ui.sitecreation.theme.defaultTemplateSlug + +const val SUB_DOMAIN = "test" +const val URL = "$SUB_DOMAIN.wordpress.com" +const val URL_CUSTOM = "$SUB_DOMAIN.host.com" +const val SITE_SLUG = "${SUB_DOMAIN}host0.wordpress.com" +val FREE_DOMAIN = DomainModel(URL, true, "", 1, false) +val PAID_DOMAIN = DomainModel(URL_CUSTOM, false, "$1", 2, true) + +const val SITE_REMOTE_ID = 1L + +val SITE_CREATION_STATE = SiteCreationState( + segmentId = 1, + siteDesign = defaultTemplateSlug, + domain = FREE_DOMAIN, +) + +val SITE_MODEL = SiteModel().apply { siteId = SITE_REMOTE_ID; url = SITE_SLUG } + +val CHECKOUT_DETAILS = DomainRegistrationCheckoutWebViewActivity.OpenCheckout.CheckoutDetails(SITE_MODEL, SITE_SLUG) +val CHECKOUT_EVENT = DomainRegistrationCompletedEvent(URL_CUSTOM, "email@host.com") + +val FETCH_SUCCESS = OnSiteChanged(1) +val FETCH_ERROR = OnSiteChanged(0).apply { error = SiteError(GENERIC_ERROR) } + +val CART_SUCCESS = OnShoppingCartCreated(mock()) +val CART_ERROR = OnShoppingCartCreated(mock()) + +val RESULT_CREATED = mock() +val RESULT_NOT_IN_LOCAL_DB = CreatedButNotFetched.NotInLocalDb(SITE_MODEL) +val RESULT_IN_CART = CreatedButNotFetched.InCart(SITE_MODEL) +val RESULT_COMPLETED = Completed(SITE_MODEL) + +val SERVICE_SUCCESS = SiteCreationServiceState(SUCCESS, Pair(SITE_REMOTE_ID, SITE_SLUG)) +val SERVICE_ERROR = SiteCreationServiceState(FAILURE, SiteCreationServiceState(CREATE_SITE)) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVMTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVMTest.kt index 8ac0ea6a7103..2708dad18238 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVMTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVMTest.kt @@ -7,14 +7,15 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.argThat +import org.mockito.kotlin.argWhere import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.eq import org.mockito.kotlin.isA import org.mockito.kotlin.mock import org.mockito.kotlin.never @@ -27,14 +28,14 @@ import org.wordpress.android.R import org.wordpress.android.fluxc.Dispatcher import org.wordpress.android.fluxc.model.experiments.Variation.Control import org.wordpress.android.fluxc.model.experiments.Variation.Treatment +import org.wordpress.android.ui.domains.DomainsRegistrationTracker import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleEmpty import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleGeneral import org.wordpress.android.ui.sitecreation.SiteCreationMainVM.SiteCreationScreenTitle.ScreenTitleStepCount +import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched.DomainRegistrationPurchased import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteCreationCompleted import org.wordpress.android.ui.sitecreation.usecases.FetchHomePageLayoutsUseCase import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig @@ -44,11 +45,11 @@ import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.wizard.WizardManager import org.wordpress.android.viewmodel.SingleLiveEvent import org.wordpress.android.viewmodel.helpers.DialogHolder +import kotlin.test.assertEquals +import kotlin.test.assertIs -private const val LOCAL_SITE_ID = 1 private const val SEGMENT_ID = 1L private const val VERTICAL = "Test Vertical" -private const val DOMAIN = "test.domain.com" private const val STEP_COUNT = 20 private const val FIRST_STEP_INDEX = 1 private const val LAST_STEP_INDEX = STEP_COUNT @@ -63,7 +64,7 @@ class SiteCreationMainVMTest : BaseUnitTest() { lateinit var navigationTargetObserver: Observer @Mock - lateinit var wizardFinishedObserver: Observer + lateinit var onCompletedObserver: Observer @Mock lateinit var wizardExitedObserver: Observer @@ -104,6 +105,9 @@ class SiteCreationMainVMTest : BaseUnitTest() { @Mock lateinit var domainPurchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig + @Mock + lateinit var domainsRegistrationTracker: DomainsRegistrationTracker + private val wizardManagerNavigatorLiveData = SingleLiveEvent() private lateinit var viewModel: SiteCreationMainVM @@ -112,13 +116,12 @@ class SiteCreationMainVMTest : BaseUnitTest() { fun setUp() { whenever(wizardManager.navigatorLiveData).thenReturn(wizardManagerNavigatorLiveData) whenever(wizardManager.showNextStep()).then { - wizardManagerNavigatorLiveData.value = siteCreationStep - Unit + run { wizardManagerNavigatorLiveData.value = siteCreationStep } } viewModel = getNewViewModel() viewModel.start(null, SiteCreationSource.UNSPECIFIED) viewModel.navigationTargetObservable.observeForever(navigationTargetObserver) - viewModel.wizardFinishedObservable.observeForever(wizardFinishedObserver) + viewModel.onCompleted.observeForever(onCompletedObserver) viewModel.dialogActionObservable.observeForever(dialogActionsObserver) viewModel.exitFlowObservable.observeForever(wizardExitedObserver) viewModel.onBackPressedObservable.observeForever(onBackPressedObserver) @@ -129,25 +132,86 @@ class SiteCreationMainVMTest : BaseUnitTest() { @Test fun domainSelectedResultsInNextStep() { - viewModel.onDomainsScreenFinished(DOMAIN) + viewModel.onDomainsScreenFinished(FREE_DOMAIN) verify(wizardManager).showNextStep() } @Test fun siteCreationStateUpdatedWithSelectedDomain() { - viewModel.onDomainsScreenFinished(DOMAIN) - assertThat(currentWizardState(viewModel).domain).isEqualTo(DOMAIN) + viewModel.onDomainsScreenFinished(FREE_DOMAIN) + assertThat(currentWizardState(viewModel).domain).isEqualTo(FREE_DOMAIN) } @Test - fun wizardFinishedInvokedOnSitePreviewCompleted() { - val state = SiteCreationCompleted(LOCAL_SITE_ID, false) - viewModel.onSitePreviewScreenFinished(state) + fun `on wizard finished is propagated`() { + viewModel.onWizardFinished(RESULT_COMPLETED) + verify(onCompletedObserver).onChanged(eq(RESULT_COMPLETED to false)) + } - val captor = ArgumentCaptor.forClass(CreateSiteState::class.java) - verify(wizardFinishedObserver).onChanged(captor.capture()) + @Test + fun `on cart created propagates details to show checkout`() { + viewModel.onCartCreated(CHECKOUT_DETAILS) + assertEquals(CHECKOUT_DETAILS, viewModel.showDomainCheckout.value) + } - assertThat(captor.value).isEqualTo(state) + @Test + fun `on cart created tracks checkout webview viewed`() { + viewModel.onCartCreated(CHECKOUT_DETAILS) + verify(domainsRegistrationTracker).trackDomainsPurchaseWebviewViewed(eq(CHECKOUT_DETAILS.site), eq(true)) + } + + @Test + fun `on cart created updates result`() { + viewModel.onCartCreated(CHECKOUT_DETAILS) + + // Assert on the private state via bundle + viewModel.writeToBundle(savedInstanceState) + verify(savedInstanceState).putParcelable( + eq(KEY_SITE_CREATION_STATE), + argWhere { it.result == RESULT_IN_CART } + ) + } + + @Test + fun `on checkout result when null shows previous step`() { + viewModel.onCheckoutResult(null) + + verify(wizardManager).onBackPressed() + verify(onBackPressedObserver).onChanged(anyOrNull()) + } + + @Test + fun `on checkout result when not null shows next step`() { + viewModel.onCartCreated(CHECKOUT_DETAILS) + + viewModel.onCheckoutResult(CHECKOUT_EVENT) + + verify(wizardManager).showNextStep() + } + + @Test + fun `on checkout result when not null updates result`() { + viewModel.onCartCreated(CHECKOUT_DETAILS) + + viewModel.onCheckoutResult(CHECKOUT_EVENT) + + assertIs(currentWizardState(viewModel).result).run { + assertEquals(CHECKOUT_DETAILS.site, site) + assertEquals(CHECKOUT_EVENT.domainName, domainName) + assertEquals(CHECKOUT_EVENT.email, email) + } + } + + @Test + fun `on progress screen finished updates result`() { + viewModel.onFreeSiteCreated(SITE_MODEL) + assertThat(currentWizardState(viewModel).result).isEqualTo(RESULT_NOT_IN_LOCAL_DB) + } + + @Test + fun `on progress screen finished shows next step`() { + viewModel.onFreeSiteCreated(SITE_MODEL) + verify(wizardManager).showNextStep() } @Test @@ -186,6 +250,7 @@ class SiteCreationMainVMTest : BaseUnitTest() { @Test fun dialogShownOnBackPressedWhenLastStepAndSiteCreationNotCompleted() { whenever(wizardManager.isLastStep()).thenReturn(true) + viewModel.onWizardCancelled() viewModel.onBackPressed() verify(dialogActionsObserver).onChanged(any()) } @@ -193,7 +258,7 @@ class SiteCreationMainVMTest : BaseUnitTest() { @Test fun flowExitedOnBackPressedWhenLastStepAndSiteCreationCompleted() { whenever(wizardManager.isLastStep()).thenReturn(true) - viewModel.onSiteCreationCompleted() + viewModel.onWizardFinished(RESULT_COMPLETED) viewModel.onBackPressed() verify(wizardExitedObserver).onChanged(anyOrNull()) } @@ -310,6 +375,7 @@ class SiteCreationMainVMTest : BaseUnitTest() { verify(tracker, never()).trackSiteCreationDomainPurchasingExperimentVariation(any()) } + @Test fun `given domain purchasing experiment on, when start in control variation, then experiment is tracked`() { whenever(domainPurchasingFeatureConfig.isEnabledState()).thenReturn(true) @@ -330,8 +396,7 @@ class SiteCreationMainVMTest : BaseUnitTest() { verify(tracker).trackSiteCreationDomainPurchasingExperimentVariation(isA()) } - private fun currentWizardState(vm: SiteCreationMainVM) = - vm.navigationTargetObservable.lastEvent!!.wizardState + private fun currentWizardState(vm: SiteCreationMainVM) = vm.navigationTargetObservable.lastEvent!!.wizardState private fun getNewViewModel() = SiteCreationMainVM( tracker, @@ -343,5 +408,6 @@ class SiteCreationMainVMTest : BaseUnitTest() { jetpackFeatureRemovalOverlayUtil, domainPurchasingExperiment, domainPurchasingFeatureConfig, + domainsRegistrationTracker, ) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt index cb0d89d48b0b..e1289edd2304 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt @@ -11,9 +11,9 @@ import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any +import org.mockito.kotlin.argWhere import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq -import org.mockito.kotlin.firstValue import org.mockito.kotlin.lastValue import org.mockito.kotlin.mock import org.mockito.kotlin.secondValue @@ -31,8 +31,8 @@ import org.wordpress.android.fluxc.store.ProductsStore import org.wordpress.android.fluxc.store.ProductsStore.OnProductsFetched import org.wordpress.android.fluxc.store.SiteStore.OnSuggestedDomains import org.wordpress.android.fluxc.store.SiteStore.SuggestDomainError -import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainModel import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainsUiState +import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainsUiState.CreateSiteButtonState import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.DomainsUiState.DomainsUiContentState import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.ListItemUiState.New import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsViewModel.ListItemUiState.New.DomainUiState.Cost @@ -75,7 +75,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { private lateinit var uiStateObserver: Observer @Mock - private lateinit var createSiteBtnObserver: Observer + private lateinit var createSiteBtnObserver: Observer @Mock private lateinit var clearBtnObserver: Observer @@ -292,17 +292,14 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { verify(clearBtnObserver, times(1)).onChanged(captor.capture()) } - /** - * Verifies that create site button is properly propagated when a domain is selected. - */ @Test - fun verifyCreateSiteBtnClickedPropagated() = testWithSuccessResponse { - val domainName = "test.domain" - viewModel.onDomainSelected(mockDomain(domainName)) + fun `verify click on the create site button emits the selected domain`() = testWithSuccessResponse { + val selectedDomain = mockDomain("test.domain") + viewModel.onDomainSelected(selectedDomain) + viewModel.onCreateSiteBtnClicked() - val captor = ArgumentCaptor.forClass(String::class.java) - verify(createSiteBtnObserver, times(1)).onChanged(captor.capture()) - assertThat(captor.firstValue).isEqualTo(domainName) + + verify(createSiteBtnObserver).onChanged(argWhere { it == selectedDomain }) } @Test @@ -320,6 +317,15 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { ) } + @Test + fun `verify create site button text is not changed when purchasing feature is OFF`() = testWithSuccessResponse { + viewModel.start() + + viewModel.onDomainSelected(mock()) + + assertIs(viewModel.uiState.value?.createSiteButtonState) + } + // region New UI private fun testNewUi(block: suspend CoroutineScope.() -> Unit) = test { @@ -340,6 +346,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { is_free = it % 2 == 0 cost = if (is_free) "Free" else "$$it.00" product_id = it + supports_privacy = !is_free } } @@ -374,6 +381,25 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { verify(productsStore).fetchProducts(eq(TYPE_DOMAINS_PRODUCT)) } + @Test + fun `verify create site button text changes when selecting a free domain`() = testNewUi { + viewModel.start() + + viewModel.onDomainSelected(mockDomain(free = true)) + + assertIs(viewModel.uiState.value?.createSiteButtonState) + } + + @Test + fun `verify create site button text changes when selecting a non-free domain`() = testNewUi { + viewModel.start() + + viewModel.onDomainSelected(mockDomain(free = false)) + + assertIs(viewModel.uiState.value?.createSiteButtonState) + } + + @Test fun `verify all domain results from api are visible`() = testWithSuccessResultNewUi { (query, results) -> viewModel.start() @@ -464,7 +490,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() { assertThat(uiState.searchInputUiState.showProgress).isEqualTo(showProgress) assertThat(uiState.searchInputUiState.showClearButton).isEqualTo(showClearButton) assertThat(uiState.contentState).isInstanceOf(DomainsUiContentState.Initial::class.java) - assertThat(uiState.createSiteButtonContainerVisibility).isEqualTo(false) + assertThat(uiState.createSiteButtonState).isNull() } /** diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/CreateSiteUseCaseTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/CreateSiteUseCaseTest.kt index 0cbf77042355..bbecfe3041ba 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/CreateSiteUseCaseTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/CreateSiteUseCaseTest.kt @@ -5,33 +5,46 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any +import org.mockito.kotlin.argThat import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.Dispatcher -import org.wordpress.android.fluxc.action.SiteAction import org.wordpress.android.fluxc.annotations.action.Action import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.fluxc.store.SiteStore.NewSitePayload import org.wordpress.android.fluxc.store.SiteStore.OnNewSiteCreated import org.wordpress.android.fluxc.store.SiteStore.SiteVisibility +import org.wordpress.android.ui.sitecreation.FREE_DOMAIN +import org.wordpress.android.ui.sitecreation.PAID_DOMAIN +import org.wordpress.android.ui.sitecreation.SITE_REMOTE_ID import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceData import org.wordpress.android.ui.sitecreation.usecases.CreateSiteUseCase import org.wordpress.android.util.UrlUtilsWrapper +import kotlin.test.assertEquals +import kotlin.test.assertNotNull private const val SITE_TITLE = "site title" -private val DUMMY_SITE_DATA: SiteCreationServiceData = SiteCreationServiceData( +private val SITE_DATA_FREE = SiteCreationServiceData( 123, "slug", - "domain", - SITE_TITLE + FREE_DOMAIN.domainName, + SITE_TITLE, + FREE_DOMAIN.isFree, +) +private val SITE_DATA_PAID = SiteCreationServiceData( + 123, + "slug", + PAID_DOMAIN.domainName, + SITE_TITLE, + PAID_DOMAIN.isFree, ) private const val LANGUAGE_ID = "lang_id" private const val TIMEZONE_ID = "timezone_id" +private val EVENT = OnNewSiteCreated(newSiteRemoteId = SITE_REMOTE_ID) @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) @@ -45,83 +58,65 @@ class CreateSiteUseCaseTest : BaseUnitTest() { @Mock private lateinit var urlUtilsWrapper: UrlUtilsWrapper private lateinit var useCase: CreateSiteUseCase - private lateinit var event: OnNewSiteCreated @Before fun setUp() { useCase = CreateSiteUseCase(dispatcher, store, urlUtilsWrapper) - event = OnNewSiteCreated(newSiteRemoteId = 123) + whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(EVENT) } } @Test fun coroutineResumedWhenResultEventDispatched() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - val resultEvent = useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - assertThat(resultEvent).isEqualTo(event) + val resultEvent = useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + assertThat(resultEvent).isEqualTo(EVENT) } @Test fun verifySiteDataPropagated() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - val captor = ArgumentCaptor.forClass(Action::class.java) - verify(dispatcher).dispatch(captor.capture()) + useCase.createSite(SITE_DATA_PAID, LANGUAGE_ID, TIMEZONE_ID) + + verify(dispatcher).dispatch(argPayload { + assertEquals(SITE_DATA_PAID.domain, siteName) + assertEquals(SITE_DATA_PAID.segmentId, segmentId) + assertEquals(SITE_DATA_PAID.title, siteTitle) + val findAvailableUrl = assertNotNull(findAvailableUrl) + findAvailableUrl + }) + } - assertThat(captor.value.type).isEqualTo(SiteAction.CREATE_NEW_SITE) - assertThat(captor.value.payload).isInstanceOf(NewSitePayload::class.java) - val payload = captor.value.payload as NewSitePayload - assertThat(payload.siteName).isEqualTo(DUMMY_SITE_DATA.domain) - assertThat(payload.segmentId).isEqualTo(DUMMY_SITE_DATA.segmentId) - assertThat(payload.siteTitle).isEqualTo(SITE_TITLE) + @Test + fun verifySiteDataWhenFreePropagatesNoFindAvailableUrl() = test { + whenever(urlUtilsWrapper.extractSubDomain(any())).thenReturn(SITE_DATA_FREE.domain) + useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + verify(dispatcher).dispatch(argPayload { + assertEquals(SITE_DATA_FREE.domain, siteName) + findAvailableUrl == null + }) } @Test fun verifyDryRunIsFalse() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - val captor = ArgumentCaptor.forClass(Action::class.java) - verify(dispatcher).dispatch(captor.capture()) - - val payload = captor.value.payload as NewSitePayload - assertThat(payload.dryRun).isEqualTo(false) + useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + verify(dispatcher).dispatch(argPayload { !dryRun }) } @Test fun verifyCreatesPublicSite() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - val captor = ArgumentCaptor.forClass(Action::class.java) - verify(dispatcher).dispatch(captor.capture()) - - val payload = captor.value.payload as NewSitePayload - assertThat(payload.visibility).isEqualTo(SiteVisibility.PUBLIC) + useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + verify(dispatcher).dispatch(argPayload { visibility == SiteVisibility.PUBLIC }) } @Test fun verifyPropagatesLanguageId() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - val captor = ArgumentCaptor.forClass(Action::class.java) - verify(dispatcher).dispatch(captor.capture()) - - val payload = captor.value.payload as NewSitePayload - assertThat(payload.language).isEqualTo(LANGUAGE_ID) + useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + verify(dispatcher).dispatch(argPayload { language == LANGUAGE_ID }) } @Test fun verifyPropagatesTimeZoneId() = test { - whenever(dispatcher.dispatch(any())).then { useCase.onNewSiteCreated(event) } - useCase.createSite(DUMMY_SITE_DATA, LANGUAGE_ID, TIMEZONE_ID) - - val captor = ArgumentCaptor.forClass(Action::class.java) - verify(dispatcher).dispatch(captor.capture()) - - val payload = captor.value.payload as NewSitePayload - assertThat(payload.timeZoneId).isEqualTo(TIMEZONE_ID) + useCase.createSite(SITE_DATA_FREE, LANGUAGE_ID, TIMEZONE_ID) + verify(dispatcher).dispatch(argPayload { timeZoneId == TIMEZONE_ID }) } } + +fun argPayload(predicate: NewSitePayload.() -> Boolean) = argThat> { predicate(payload) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModelTest.kt index 9c31c26cfd3b..8d1d17845f05 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/previews/SitePreviewViewModelTest.kt @@ -1,76 +1,53 @@ package org.wordpress.android.ui.sitecreation.previews -import android.os.Bundle import androidx.lifecycle.Observer import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceTimeBy -import kotlinx.coroutines.test.advanceUntilIdle import org.assertj.core.api.Assertions.assertThat import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.eq -import org.mockito.kotlin.notNull +import org.mockito.kotlin.isA +import org.mockito.kotlin.mock +import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.Dispatcher -import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged -import org.wordpress.android.fluxc.store.SiteStore.SiteError -import org.wordpress.android.fluxc.store.SiteStore.SiteErrorType.GENERIC_ERROR +import org.wordpress.android.ui.sitecreation.FETCH_ERROR +import org.wordpress.android.ui.sitecreation.FETCH_SUCCESS +import org.wordpress.android.ui.sitecreation.RESULT_COMPLETED +import org.wordpress.android.ui.sitecreation.RESULT_CREATED +import org.wordpress.android.ui.sitecreation.RESULT_NOT_IN_LOCAL_DB +import org.wordpress.android.ui.sitecreation.SITE_CREATION_STATE +import org.wordpress.android.ui.sitecreation.SITE_MODEL +import org.wordpress.android.ui.sitecreation.SITE_REMOTE_ID +import org.wordpress.android.ui.sitecreation.SUB_DOMAIN +import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created import org.wordpress.android.ui.sitecreation.SiteCreationState +import org.wordpress.android.ui.sitecreation.URL import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteCreationCompleted -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotCreated -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.CreateSiteState.SiteNotInLocalDb -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewStartServiceData import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewContentUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenErrorUiState.SitePreviewConnectionErrorUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenErrorUiState.SitePreviewGenericErrorUiState -import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewFullscreenProgressUiState import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewWebErrorUiState +import org.wordpress.android.ui.sitecreation.progress.LOADING_STATE_TEXT_ANIMATION_DELAY import org.wordpress.android.ui.sitecreation.services.FetchWpComSiteUseCase -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.CREATE_SITE -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.FAILURE -import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.SUCCESS -import org.wordpress.android.ui.sitecreation.theme.defaultTemplateSlug -import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.util.UrlUtilsWrapper -import org.wordpress.android.util.extensions.getParcelableCompat - -private const val SUB_DOMAIN = "test" -private const val DOMAIN = ".wordpress.com" -private const val URL = "$SUB_DOMAIN$DOMAIN" -private const val REMOTE_SITE_ID = 1L -private const val LOCAL_SITE_ID = 2 -private val SITE_CREATION_STATE = SiteCreationState(segmentId = 1, siteDesign = defaultTemplateSlug, domain = URL) @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) class SitePreviewViewModelTest : BaseUnitTest() { - @Mock - private lateinit var dispatcher: Dispatcher - - @Mock - private lateinit var siteStore: SiteStore - - @Mock - private lateinit var bundle: Bundle - - @Mock - private lateinit var fetchWpComUseCase: FetchWpComSiteUseCase - - @Mock - private lateinit var networkUtils: NetworkUtilsWrapper + private var dispatcher = mock() + private var siteStore = mock() + private var fetchWpComSiteUseCase = mock() @Mock private lateinit var urlUtils: UrlUtilsWrapper @@ -82,16 +59,7 @@ class SitePreviewViewModelTest : BaseUnitTest() { private lateinit var uiStateObserver: Observer @Mock - private lateinit var startServiceObserver: Observer - - @Mock - private lateinit var onHelpedClickedObserver: Observer - - @Mock - private lateinit var onCancelWizardClickedObserver: Observer - - @Mock - private lateinit var onOkClickedObserver: Observer + private lateinit var onOkClickedObserver: Observer @Mock private lateinit var preloadPreviewObserver: Observer @@ -103,149 +71,47 @@ class SitePreviewViewModelTest : BaseUnitTest() { viewModel = SitePreviewViewModel( dispatcher, siteStore, - fetchWpComUseCase, - networkUtils, + fetchWpComSiteUseCase, urlUtils, tracker, testDispatcher(), testDispatcher() ) viewModel.uiState.observeForever(uiStateObserver) - viewModel.startCreateSiteService.observeForever(startServiceObserver) - viewModel.onHelpClicked.observeForever(onHelpedClickedObserver) - viewModel.onCancelWizardClicked.observeForever(onCancelWizardClickedObserver) viewModel.onOkButtonClicked.observeForever(onOkClickedObserver) viewModel.preloadPreview.observeForever(preloadPreviewObserver) - whenever(networkUtils.isNetworkAvailable()).thenReturn(true) - whenever(urlUtils.extractSubDomain(URL)).thenReturn(SUB_DOMAIN) - whenever(urlUtils.addUrlSchemeIfNeeded(URL, true)).thenReturn(URL) - whenever(urlUtils.removeScheme(URL)).thenReturn(URL) - whenever(siteStore.getSiteBySiteId(REMOTE_SITE_ID)).thenReturn(createLocalDbSiteModelId()) - } - - private fun testWithSuccessResponse(block: suspend CoroutineScope.() -> T) { - test { - whenever(fetchWpComUseCase.fetchSiteWithRetry(REMOTE_SITE_ID)) - .thenReturn(OnSiteChanged(1)) - block() - } - } - - private fun testWithErrorResponse(block: suspend CoroutineScope.() -> T) { - test { - val onSiteChanged = OnSiteChanged(0) - onSiteChanged.error = SiteError(GENERIC_ERROR) - whenever(fetchWpComUseCase.fetchSiteWithRetry(REMOTE_SITE_ID)) - .thenReturn(onSiteChanged) - block() - } - } - - @Test - fun `progress shown on start`() = test { - initViewModel() - - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewFullscreenProgressUiState::class.java) - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) // complete flow - } - - @Test - @Ignore("This test runs indefinitely without completing due to the way it is structured to test the animate field.") - fun `ProgressUiState's animate field is false only for first emitted event`() = test { - initViewModel() - assertThat((viewModel.uiState.value as SitePreviewFullscreenProgressUiState).animate).isFalse() - - (1..100).forEach { - advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) - assertThat((viewModel.uiState.value as SitePreviewFullscreenProgressUiState).animate).isTrue() - } - } - - @Test - @Ignore("This test runs indefinitely without completing due to the way it is structured to test the loading state.") - fun `ProgressUiState's text changes every LOADING_STATE_TEXT_ANIMATION_DELAY seconds`() = test { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) // complete flow - - (1..100).forEach { - val lastTextId = (viewModel.uiState.value as SitePreviewFullscreenProgressUiState).loadingTextResId - advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) - assertThat((viewModel.uiState.value as SitePreviewFullscreenProgressUiState).loadingTextResId) - .isNotEqualTo(lastTextId) - } - } - @Test - fun `service started on start`() = test { - initViewModel() - - assertThat(viewModel.startCreateSiteService.value).isNotNull - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) // complete flow - } - - @Test - fun `error shown on start when internet access not available`() = test { - whenever(networkUtils.isNetworkAvailable()).thenReturn(false) - initViewModel() - advanceUntilIdle() // skip delays - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewConnectionErrorUiState::class.java) - } - - @Test - fun `error shown on service failure`() { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceFailureState()) - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewGenericErrorUiState::class.java) - } - - @Test - fun `displaying error screen cancels the progress animation job`() = test { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceFailureState()) - (1..100).forEach { - advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewGenericErrorUiState::class.java) - } + whenever(urlUtils.extractSubDomain(any())).thenReturn(SUB_DOMAIN) + whenever(urlUtils.addUrlSchemeIfNeeded(any(), eq(true))).thenReturn(URL) + whenever(siteStore.getSiteBySiteId(SITE_REMOTE_ID)).thenReturn(SITE_MODEL) } @Test - fun `service started on retry`() { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceFailureState()) - viewModel.retry() - assertThat(viewModel.startCreateSiteService.value).isNotNull + fun `on start fetches site by remote id when result is created`() = testWith(FETCH_SUCCESS) { + startViewModel(SITE_CREATION_STATE.copy(result = RESULT_NOT_IN_LOCAL_DB)) + verify(fetchWpComSiteUseCase).fetchSiteWithRetry(SITE_REMOTE_ID) } @Test - fun `on Help click is propagated`() { - viewModel.onHelpClicked() - verify(onHelpedClickedObserver).onChanged(null) - } - - @Test - fun `on WizardCanceled click is propagated`() { - viewModel.onCancelWizardClicked() - assertThat(viewModel.onCancelWizardClicked.value).isEqualTo(SiteNotCreated) - } - - @Test - fun `on OK click is propagated`() { + fun `on start does not show preview when fetching fails`() = testWith(FETCH_ERROR) { + startViewModel() + verify(siteStore, never()).getSiteBySiteId(SITE_REMOTE_ID) viewModel.onOkButtonClicked() - assertThat(viewModel.onOkButtonClicked.value).isEqualTo(SiteNotCreated) + verify(uiStateObserver, never()).onChanged(isA()) } @Test fun `show content on UrlLoaded`() { - initViewModel() + startViewModel() viewModel.onUrlLoaded() assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewContentUiState::class.java) } @Test fun `displaying content cancels the progress animation job`() = test { - initViewModel() + startViewModel() viewModel.onUrlLoaded() - (1..100).forEach { + repeat(100) { advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewContentUiState::class.java) } @@ -253,131 +119,35 @@ class SitePreviewViewModelTest : BaseUnitTest() { @Test fun `show webview empty screen on WebViewError`() { - initViewModel() + startViewModel() viewModel.onWebViewError() assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewWebErrorUiState::class.java) } @Test - fun `start pre-loading WebView on service success`() = testWithSuccessResponse { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) + fun `on start preloads the preview when result is Completed`() { + startViewModel(SITE_CREATION_STATE.copy(result = RESULT_COMPLETED)) assertThat(viewModel.preloadPreview.value).isEqualTo(URL) } @Test - fun `fetch newly created SiteModel on service success`() = testWithSuccessResponse { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) - verify(fetchWpComUseCase).fetchSiteWithRetry(REMOTE_SITE_ID) - } - - @Test - fun `CreateSiteState is SiteNotCreated on init`() { - initViewModel() - assertThat(getCreateSiteState()).isEqualTo(SiteNotCreated) - } - - @Test - fun `CreateSiteState is SiteCreationCompleted on fetchFromRemote success`() = testWithSuccessResponse { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) - assertThat(getCreateSiteState()).isEqualTo(SiteCreationCompleted(LOCAL_SITE_ID, false)) - } - - @Test - fun `CreateSiteState is NotInLocalDb on fetchFromRemote failure`() = testWithErrorResponse { - initViewModel() - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) - assertThat(getCreateSiteState()).isEqualTo(SiteNotInLocalDb(REMOTE_SITE_ID, false)) - } - - @Test - fun `CreateSiteState is saved into bundle`() { - initViewModel(null) - - viewModel.writeToBundle(bundle) - - verify(bundle).putParcelable(eq(KEY_CREATE_SITE_STATE), notNull()) - } - - @Test - fun `show fullscreen progress when restoring from SiteNotCreated state`() = testWithSuccessResponse { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)).thenReturn(SiteNotCreated) - initViewModel(bundle) - - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewFullscreenProgressUiState::class.java) - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) // complete flow - } - - @Test - fun `service started when restoring from SiteNotCreated state`() { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)).thenReturn(SiteNotCreated) - initViewModel(bundle) - - assertThat(viewModel.startCreateSiteService.value).isNotNull - } - - @Test - fun `show fullscreen progress when restoring from SiteNotInLocalDb state`() = testWithSuccessResponse { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)).thenReturn(SiteNotCreated) - initViewModel(bundle) - - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewFullscreenProgressUiState::class.java) - viewModel.onSiteCreationServiceStateUpdated(createServiceSuccessState()) // complete flow - } - - @Test - fun `start pre-loading WebView when restoring from SiteNotInLocalDb state`() = testWithSuccessResponse { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)) - .thenReturn(SiteNotInLocalDb(REMOTE_SITE_ID, false)) - initViewModel(bundle) - - assertThat(viewModel.uiState.value).isInstanceOf(SitePreviewFullscreenProgressUiState::class.java) - } - - @Test - fun `fetch newly created SiteModel when restoring from SiteNotInLocalDb state`() = testWithSuccessResponse { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)) - .thenReturn(SiteNotInLocalDb(REMOTE_SITE_ID, false)) - initViewModel(bundle) - - verify(fetchWpComUseCase).fetchSiteWithRetry(REMOTE_SITE_ID) - } - - @Test - fun `start pre-loading WebView when restoring from SiteCreationCompleted state`() { - whenever(bundle.getParcelableCompat(KEY_CREATE_SITE_STATE)) - .thenReturn(SiteCreationCompleted(LOCAL_SITE_ID, false)) - initViewModel(bundle) - - assertThat(viewModel.preloadPreview.value).isEqualTo(URL) - } - - private fun initViewModel(savedState: Bundle? = null) { - viewModel.start(SITE_CREATION_STATE, savedState) + fun `on ok button click is propagated`() = testWith(FETCH_SUCCESS) { + startViewModel() + viewModel.onOkButtonClicked() + verify(onOkClickedObserver).onChanged(anyOrNull()) } - private fun createServiceFailureState(): SiteCreationServiceState { - val stateBeforeFailure = SiteCreationServiceState(CREATE_SITE) - return SiteCreationServiceState(FAILURE, stateBeforeFailure) - } + // region Helpers - private fun createServiceSuccessState(): SiteCreationServiceState { - return SiteCreationServiceState(SUCCESS, Pair(REMOTE_SITE_ID, URL)) + private fun testWith(response: OnSiteChanged, block: suspend CoroutineScope.() -> Unit) = test { + whenever(fetchWpComSiteUseCase.fetchSiteWithRetry(SITE_REMOTE_ID)).thenReturn(response) + block() } - private fun createLocalDbSiteModelId(): SiteModel { - val localDbSiteModel = SiteModel() - localDbSiteModel.id = LOCAL_SITE_ID - return localDbSiteModel + private fun startViewModel(state: SiteCreationState = SITE_CREATION_STATE.copy(result = RESULT_CREATED)) { + whenever(RESULT_CREATED.site).thenReturn(SITE_MODEL) + viewModel.start(state) } - /** - * `createSiteState` is a private property -> get its value using `onOkButtonClicked` - */ - private fun getCreateSiteState(): CreateSiteState? { - viewModel.onOkButtonClicked() - return viewModel.onOkButtonClicked.value - } + // endregion } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt new file mode 100644 index 000000000000..7b178d89f60b --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt @@ -0,0 +1,269 @@ +package org.wordpress.android.ui.sitecreation.progress + +import androidx.lifecycle.Observer +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.advanceUntilIdle +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.any +import org.mockito.kotlin.argThat +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.atMost +import org.mockito.kotlin.check +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.eq +import org.mockito.kotlin.isNull +import org.mockito.kotlin.mock +import org.mockito.kotlin.refEq +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartCreated +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewActivity.OpenCheckout.CheckoutDetails +import org.wordpress.android.ui.domains.usecases.CreateCartUseCase +import org.wordpress.android.ui.sitecreation.CART_ERROR +import org.wordpress.android.ui.sitecreation.CART_SUCCESS +import org.wordpress.android.ui.sitecreation.PAID_DOMAIN +import org.wordpress.android.ui.sitecreation.RESULT_IN_CART +import org.wordpress.android.ui.sitecreation.SERVICE_ERROR +import org.wordpress.android.ui.sitecreation.SERVICE_SUCCESS +import org.wordpress.android.ui.sitecreation.SITE_CREATION_STATE +import org.wordpress.android.ui.sitecreation.SITE_REMOTE_ID +import org.wordpress.android.ui.sitecreation.SITE_SLUG +import org.wordpress.android.ui.sitecreation.SiteCreationState +import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.ConnectionError +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.GenericError +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Loading +import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.StartServiceData +import org.wordpress.android.util.NetworkUtilsWrapper +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertIs +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class SiteCreationProgressViewModelTest : BaseUnitTest() { + private var networkUtils = mock() + private var tracker = mock() + private val createCartUseCase = mock() + + private val uiStateObserver = mock>() + private val startServiceObserver = mock>() + private val onHelpClickedObserver = mock>() + private val onCancelWizardClickedObserver = mock>() + private val onRemoteSiteCreatedObserver = mock>() + private val onCartCreatedObserver = mock>() + + private lateinit var viewModel: SiteCreationProgressViewModel + + @Before + fun setUp() { + viewModel = SiteCreationProgressViewModel( + networkUtils, + tracker, + createCartUseCase, + testDispatcher(), + ) + viewModel.uiState.observeForever(uiStateObserver) + viewModel.startCreateSiteService.observeForever(startServiceObserver) + viewModel.onHelpClicked.observeForever(onHelpClickedObserver) + viewModel.onCancelWizardClicked.observeForever(onCancelWizardClickedObserver) + viewModel.onFreeSiteCreated.observeForever(onRemoteSiteCreatedObserver) + viewModel.onCartCreated.observeForever(onCartCreatedObserver) + + whenever(networkUtils.isNetworkAvailable()).thenReturn(true) + } + + @Test + fun `on start shows progress`() = test { + startViewModel() + assertIs(viewModel.uiState.value) + } + + @Test + fun `on start emits service event`() = test { + startViewModel() + assertNotNull(viewModel.startCreateSiteService.value) + } + + @Test + fun `on start emits service event for free domains with isFree true`() = test { + startViewModel(SITE_CREATION_STATE) + val request = assertNotNull(viewModel.startCreateSiteService.value).serviceData + assertTrue(request.isFree) + } + + @Test + fun `on start emits service event for paid domains with isFree false`() = test { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + val request = assertNotNull(viewModel.startCreateSiteService.value).serviceData + assertFalse(request.isFree) + } + + @Test + fun `on start shows error when network is not available`() = test { + whenever(networkUtils.isNetworkAvailable()).thenReturn(false) + startViewModel() + advanceUntilIdle() + assertIs(viewModel.uiState.value) + } + + @Test + fun `on start shows first loading text without animation`() = test { + startViewModel() + verify(uiStateObserver).onChanged(check { !it.animate }) + } + + @Test + fun `on start changes the loading text with animation after delay`() = test { + startViewModel() + advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) + verify(uiStateObserver).onChanged(check { it.animate }) + } + + @Test + fun `on start changes the loading text with animation after delay 4 times`() = test { + startViewModel() + val captor = argumentCaptor() + (1..9).forEach { + verify(uiStateObserver, atMost(it)).onChanged(captor.capture()) + advanceTimeBy(LOADING_STATE_TEXT_ANIMATION_DELAY) + } + assertThat(captor.allValues.distinctBy { it.loadingTextResId }).hasSize(4) + } + + @Test + fun `on retry click emits service event with the previous result`() { + startViewModel() + viewModel.onSiteCreationServiceStateUpdated(SERVICE_ERROR) + viewModel.retry() + assertEquals(viewModel.startCreateSiteService.value?.previousState, SERVICE_ERROR.payload) + } + + @Test + fun `on help click is propagated`() { + startViewModel() + viewModel.onHelpClicked() + verify(onHelpClickedObserver).onChanged(isNull()) + } + + @Test + fun `on cancel wizard click is propagated`() { + startViewModel() + viewModel.onCancelWizardClicked() + verify(onCancelWizardClickedObserver).onChanged(isNull()) + } + + @Test + fun `on service success propagates site`() { + startViewModel() + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + verify(onRemoteSiteCreatedObserver).onChanged(argThat { + assertEquals(SITE_REMOTE_ID, siteId) + url == SITE_SLUG + }) + } + + @Test + fun `on service success for paid domain creates cart`() = test { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + verify(createCartUseCase).execute( + any(), + eq(PAID_DOMAIN.productId), + eq(PAID_DOMAIN.domainName), + eq(PAID_DOMAIN.supportsPrivacy), + any(), + ) + } + + @Test + fun `on cart success propagates checkout details`() = testWith(CART_SUCCESS) { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + verify(onCartCreatedObserver).onChanged(argThat { + assertEquals(SITE_REMOTE_ID, site.siteId) + assertEquals(SITE_SLUG, site.url) + domainName == PAID_DOMAIN.domainName + }) + } + + @Test + fun `on cart failure shows generic error`() = testWith(CART_ERROR) { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + assertIs(viewModel.uiState.value) + } + + @Test + fun `on service failure shows generic error`() { + startViewModel() + viewModel.onSiteCreationServiceStateUpdated(SERVICE_ERROR) + assertIs(viewModel.uiState.value) + } + + @Test + fun `on restart with same paid domain reuses previous blog to create new cart`() = testWith(CART_SUCCESS) { + val state = SITE_CREATION_STATE.copy(domain = PAID_DOMAIN) + startViewModel(state) + val previous = SiteModel().apply { siteId = 9L;url = "blog.wordpress.com" } + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS.copy(payload = previous.siteId to previous.url)) + + startViewModel(state.copy(result = RESULT_IN_CART)) + + verify(startServiceObserver, atMost(1)).onChanged(any()) + verify(createCartUseCase).execute( + refEq(previous), + eq(PAID_DOMAIN.productId), + eq(PAID_DOMAIN.domainName), + eq(PAID_DOMAIN.supportsPrivacy), + any() + ) + } + + @Test + fun `on restart with different paid domain emits service event`() = testWith(CART_SUCCESS) { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN.copy(domainName = "different"))) + + verify(startServiceObserver, times(2)).onChanged(any()) + } + + @Test + fun `on restart with free domain emits service event`() = testWith(CART_SUCCESS) { + startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN)) + viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS) + clearInvocations(createCartUseCase) + + startViewModel(SITE_CREATION_STATE) + + verify(startServiceObserver, times(2)).onChanged(any()) + verifyNoMoreInteractions(createCartUseCase) + } + + // region Helpers + private fun testWith(response: OnShoppingCartCreated, block: suspend CoroutineScope.() -> Unit) = test { + whenever(createCartUseCase.execute(any(), any(), any(), any(), any())).thenReturn(response) + block() + } + + private fun startViewModel(state: SiteCreationState = SITE_CREATION_STATE) { + viewModel.start(state) + } + + // endregion +} diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManagerTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManagerTest.kt index 3b76e62a929a..a70333b10838 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManagerTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/services/SiteCreationServiceManagerTest.kt @@ -34,7 +34,8 @@ private val DUMMY_SITE_DATA: SiteCreationServiceData = SiteCreationServiceData( 123, "slug", "domain", - null + null, + true, ) private val IDLE_STATE = SiteCreationServiceState(IDLE) diff --git a/build.gradle b/build.gradle index fd6a860540c7..5a96ad6fd395 100644 --- a/build.gradle +++ b/build.gradle @@ -20,9 +20,9 @@ ext { automatticRestVersion = '1.0.8' automatticStoriesVersion = '2.0.0' automatticTracksVersion = '2.2.0' - gutenbergMobileVersion = 'v1.93.0-alpha2' + gutenbergMobileVersion = 'v1.93.0' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = 'trunk-700df45f317e7aecfd2cb73a6cfa39b2f9b7de81' + wordPressFluxCVersion = 'trunk-1ca49e91927fd4bfb1a9b84dd90d8c794deb4fe7' wordPressLoginVersion = '1.3.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' diff --git a/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v11_read_sites_70135762.json b/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v11_read_sites_70135762.json new file mode 100644 index 000000000000..5b43b1de56c1 --- /dev/null +++ b/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v11_read_sites_70135762.json @@ -0,0 +1,92 @@ +{ + "request": { + "urlPath": "/rest/v1.1/read/sites/70135762", + "method": "GET", + "queryParameters": { + "locale": { + "matches": "(.*)" + } + } + }, + "response": { + "status": 200, + "jsonBody": { + "ID": 70135762, + "name": "Longreads", + "description": "The best longform stories on the web", + "URL": "http:\/\/longreads.com", + "jetpack": false, + "jetpack_connection": false, + "subscribers_count": 27, + "lang": false, + "icon": { + "img": "https:\/\/secure.gravatar.com\/blavatar\/e68667ec6ee7cdd0c6b5416a84c52a9c", + "ico": "https:\/\/secure.gravatar.com\/blavatar\/e68667ec6ee7cdd0c6b5416a84c52a9c" + }, + "logo": { + "id": 0, + "sizes": [], + "url": "" + }, + "visible": null, + "is_private": false, + "is_coming_soon": false, + "is_following": false, + "organization_id": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/help", + "posts": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/posts\/", + "comments": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/comments\/", + "xmlrpc": "https:\/\/longreadsblog.wordpress.com\/xmlrpc.php" + } + }, + "launch_status": false, + "site_migration": null, + "is_fse_active": false, + "is_fse_eligible": false, + "is_core_site_editor_enabled": false, + "is_wpcom_atomic": false, + "is_wpcom_staging_site": false, + "capabilities": { + "edit_pages": false, + "edit_posts": false, + "edit_others_posts": false, + "edit_theme_options": false, + "list_users": false, + "manage_categories": false, + "manage_options": false, + "publish_posts": false, + "upload_files": false, + "view_stats": false + }, + "is_multi_author": true, + "header_image": false, + "owner": { + "ID": 26957695, + "login": "a8cuser", + "name": "Automattic", + "first_name": "Automattic", + "last_name": "", + "nice_name": "a8cuser", + "URL": "", + "avatar_URL": "https:\/\/1.gravatar.com\/avatar\/a64c4a50f3f38f02cd27a9bfb3f11b62?s=96&d=identicon&r=G", + "profile_URL": "https:\/\/en.gravatar.com\/a8cuser", + "ip_address": false, + "site_visible": true, + "has_avatar": true + }, + "subscription": { + "delivery_methods": { + "email": null, + "notification": { + "send_posts": false + } + } + }, + "is_blocked": false, + "unseen_count": 0 + } + } +} diff --git a/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v12_read_sites_70135762_posts.json b/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v12_read_sites_70135762_posts.json new file mode 100644 index 000000000000..ef3594ba2cc5 --- /dev/null +++ b/libs/mocks/src/main/assets/mocks/mappings/wpcom/reader/rest_v12_read_sites_70135762_posts.json @@ -0,0 +1,5089 @@ +{ + "request": { + "urlPath": "/rest/v1.2/read/sites/70135762/posts/", + "method": "GET", + "queryParameters": { + "locale": { + "matches": "(.*)" + }, + "meta": { + "equalTo": "site,likes" + } + } + }, + "response": { + "status": 200, + "jsonBody": { + "found": 10, + "posts": [ + { + "ID": 159053, + "site_ID": 70135762, + "author": { + "ID": 217140548, + "login": "jnm0739", + "email": false, + "name": "Joshua N. Miller", + "first_name": "Joshua", + "last_name": "Miller", + "nice_name": "jnm0739", + "URL": "http:\/\/joshuanaimiller.wordpress.com", + "avatar_URL": "https:\/\/0.gravatar.com\/avatar\/90f002d3d6ad426984b72eebd4e5d185?s=96&d=identicon&r=G", + "profile_URL": "https:\/\/en.gravatar.com\/jnm0739", + "site_ID": 204830107, + "has_avatar": false + }, + "date": "2022-10-20T06:00:58-04:00", + "modified": "2022-10-19T16:56:17-04:00", + "title": "Anatomy of the Mask: A Reading List on Superhero Comics", + "URL": "http:\/\/longreads.com\/2022\/10\/20\/anatomy-of-the-mask-superheroes-comics-reading-list\/", + "short_URL": "https:\/\/wp.me\/p4KhvY-Fnn", + "content": "

By Joshua N. Miller<\/span><\/i><\/p>\n

In 2019, Marvel Comics was getting ready to celebrate its 80th anniversary. It had begun as Timely Comics, and quickly came to dominate the landscape with superheroes like the Human Torch and Namor the Submariner; now, for a special graphic-novel collection, the publisher invited superstar writer Art Spiegelman to write an introduction reflecting on Marvel’s legacy. There was just one issue: They asked him to compromise his own legacy to do so.<\/span><\/p>\n

Spiegelman is best known for his independent graphic novel <\/span>Maus,<\/span><\/i> which retold his father\u2019s experience surviving the Holocaust. Yet, when he compared then-president Donald Trump to the Red Skull, the fascist supervillain leader of a Nazi organization known as Hydra, Marvel balked. Demanding that a Jewish writer revise his material for the sake of <\/span>remaining apolitical<\/span><\/a> felt particularly disingenuous, given that Captain America made his 1941 debut punching Hitler in the face on the cover of his first issue<\/span>. Over the years, Marvel writers had used superheroes to explore myriad political and social issues \u2014 sometimes explicitly, sometimes by merely existing. The success of 2018\u2019s <\/span>Spider-Man: Into the Spider-Verse,<\/span><\/i> and the <\/span>Spidersona trend<\/span><\/a> that followed it, attests to the positive impact diverse representation can have on audiences.<\/span><\/p>\n

Superhero comics aren\u2019t <\/span>only<\/span><\/i> political, but they\u2019ve nearly always been political. Since Superman\u2019s debut first made the genre mainstream, superheroes and their stories have advocated for social justice. And while some writers (and the corporations that employ them) may have lost sight of this reality, the communities these heroes represent can see when the forces that be abdicate the responsibility the heroes gladly shoulder. The essays collected below explore how superhero comics capture the lived experiences of marginalized communities \u2014 as well as how some comics have only served to stigmatize them.<\/span><\/p>\n

Golden Age Superheroes Were Shaped By the Rise of Fascism<\/span><\/a> (Art Spiegelman, <\/span>The Guardian<\/span><\/i>, August 2019)<\/span><\/h2>\n

In recalling the origins of the superhero genre, Spiegelman stresses that the immaturity often ascribed to comic books was as prevalent in the 1930s as it is in the present. If there\u2019s any notable difference, it likely lies in the fact that publishers themselves were aware of this and consequently chose not to prioritize making the high-quality products we see today. (\u201cJust give them a lot of action and don\u2019t use too many words,\u201d publisher Martin Goodman once told Stan Lee.) Though Superman\u2019s debut shifted the medium by introducing an archetype that captured the hearts (and dimes) of millions of readers, the sentiment that comic books were for immature audiences endured. But the adventures of these heroes and the lives of the creators who made them tell a different tale.<\/span><\/p>\n

Bold as it was to introduce Captain America by having him punch Hitler on the cover of his first issue in 1941, the impact of his debut is better appreciated if you understand how tolerant the U.S. was toward Nazi sympathizers until the country properly entered World War II. Just two years prior to Cap\u2019s debut, <\/span>thousands of members of the German American Bund rallied in New York to express their approval of Hitler\u2019s antisemitic sentiments<\/span><\/a>. The sales of superhero comics began to dwindle after the war, <\/span>which not only suggests that consumers were aware of their political nature, but implies that publishers were willing to exploit those politics for profit.<\/span><\/p>\n

The pioneers behind this embryonic medium based in New York were predominantly Jewish and from ethnic minority backgrounds. It wasn\u2019t just Siegel and Shuster, but a whole generation of recent immigrants and their children \u2013 those most vulnerable to the ravages of the great depression \u2013 who were especially attuned to the rise of virulent antisemitism in Germany. They created the American\u00a0\u00dcbermenschen\u00a0who fought for a nation that would at least nominally welcome \u201cyour tired, your poor, your huddled masses yearning to breathe free.\u201d<\/span><\/p><\/blockquote>\n

Superman is Jewish: The Hebrew Roots of America\u2019s Greatest Superhero<\/span><\/a> (Rich Goldstein, <\/span>The Daily Beast<\/span><\/i>, July 2017)<\/span><\/h2>\n

Much of Michael Chabon\u2019s The Adventures of Kavalier & Klay<\/em><\/a> is based on the lives of Jerry Siegel, Joe Shuster, Stan Lee, and other comic-book creators.<\/p><\/blockquote>\n

Straight to the point, Goldstein opens his essay by making an important observation: Superman owes his stranger-in-a-strange-land origin to the Jewish heritage of his creators, Jerry Siegel and Joe Shuster. But his roots are often overshadowed by his association with American culture. Contemporary comics frequently depict Superman with American iconography, even though he\u2019s repeatedly acted as a hero for Earth and beyond. So it\u2019s not surprising to think that readers would try to compare him to Jesus Christ, given the important role that Christianity plays within traditional American values. Yet, hyper-fixating on Clark\u2019s Christlike attributes serves to obfuscate the superhero\u2019s Jewish origins.<\/p>\n

Here was a being who had immigrated to a land that supposedly offered the prospects of a better life, and changed his name (Kal-El to Clark Kent) to do so\u00a0 \u2014 just as some Jewish families who immigrated to the U.S. changed their names to avoid prejudice. Goldstein posits that the antisemitic sentiments of the time would have gotten Superman\u2019s comic cancelled before it even began, and invites the reader to question how warmly the character would have been received if his Jewish influences were more explicit. More importantly, however, his article affirms the fact that the creation of Superman \u2014 and the rise of the superhero genre \u2014 should be credited to the imaginations of Jewish creators who produced a hero that stood against the oppression they faced.<\/span><\/p>\n

Superman is as American as apple pie, in that both have their origins in the Middle East. Apples, because they are thought to have been first domesticated in Turkey, and Superman, because of his oftentimes overlooked Jewish heritage.<\/span><\/p><\/blockquote>\n

House of X \/ Power of X Moves Mutants Forward<\/span><\/a> (Stephanie Williams, <\/span>SYFY<\/span><\/i>, January 2020)<\/span><\/h2>\n

Even those largely unfamiliar with superhero comics are likely aware of the X-Men. But before the blockbuster sales and long-running film franchise, the beloved mutants came to prominence thanks to the efforts of Len Wein, who created characters like Storm and Wolverine, and <\/span>Chris Claremont<\/span><\/a>, who confronted them with dilemmas that blurred the traditional lines of good and evil. At the heart of the franchise\u2019s moral ambiguity is the ideological schism between the X-Men founder Charles Xavier<\/span> (Professor X), who seeks to protect mutants and mankind despite the latter\u2019s extreme prejudices against the former, and Erik Lensherr (Magneto), who prioritizes the well-being of mutants above all else. <\/span>The duo has often been compared to Martin Luther King Jr. and Malcolm X for the characters’ respective beliefs<\/span><\/a>, but since the X-Men were created any significant strides toward the dreams of either camp have been brief \u2014 if they existed at all.\u00a0<\/span><\/p>\n

That changed in 2019 with the debut of <\/span>House of X \/ Powers of X<\/span><\/i><\/a>. Spearheaded by creators Jonathan Hickman, Pepe Larraz, and R.B. Silva, <\/span>HOXPOX<\/span><\/i> offered mutants a way forward that appeased both Xavier\u2019s accomodationism and Lensherr\u2019s hardline approach: separation. The first issue lays out a broad-based mutant-led effort to create a culture detached from mankind. As Williams notes in her review, part of the appeal of the comic\u2019s premise lies in the fact that mutants finally \u201cget out of their own way\u201d; recognizing how paralyzed they\u2019ve been, they acknowledge that the only way to advance is to de-center the desires of the community that so despised them. Three years after their new culture\u2019s founding, the mutants still face opponents bent on their destruction. The difference now is that extinction no longer lurks in every defeat. On the contrary, every victory against those who seek to destroy them asserts that they, and the marginalized communities they\u2019ve been thought to represent, owe nothing to their oppressors when it comes to their survival.<\/span><\/p>\n

The safety and future for all mutants becomes the only goal, and there is no trying to continue to convince humans they are worthy of occupying the same space. It\u2019s proven time and time again to be lethal to incorporate humans into their plans. The focus is now Krakoa and making sure it remains a place where mutants can truly be free \u2014 all mutants, not just the ones who adhere to a specific ideology. There are still mutants who lose their lives in order to secure the future of Krakoa, but at least it’s for the greater good and not for selfish men.<\/span><\/p><\/blockquote>\n

\u2018<\/span>House of M\u2019 and the Vilification of Mental Illness<\/span><\/a> (Lia Williamson, <\/span>AIPT Comics<\/span><\/i>, August 2021)<\/span><\/h2>\n

While Wanda Maximoff\u2019s popularity has certainly been bolstered by her appearances in the Marvel Cinematic Universe, her character has a deep history within the Marvel comics. Introduced in the first issues of <\/span>X-Men<\/span><\/i>, Wanda (Scarlet Witch) was originally a villain operating with her brother Pietro (Quicksilver) as a member of Magneto\u2019s Brotherhood of Evil Mutants. Over the decades, however, her allegiances changed, and she became a prominent member of the Avengers. Like most other characters, she\u2019s gone through her fair share of ups and downs over the course of the past few decades, but none quite compare to the hardships she faced during the 2005 event <\/span>House of M<\/span><\/i>.<\/span><\/p>\n

Most Marvel comics fans recall the event as the time when Wanda experiences a mental breakdown and loses control of her reality-changing powers. The consequences for these episodes are dire: She\u2019s manipulated into creating an alternate reality where mutants aren\u2019t hated, and subsequently depowers nearly all mutants when that reality is compromised. While all superhero parties involved were aware of Wanda\u2019s poor mental state and how she was manipulated, since the comic\u2019s release she has shouldered most of the blame for the tragedy. By dissecting the story, Williamson opens a dialogue regarding the treatment of the mentally ill in comics \u2014 and concludes that, much like Professor X and Magneto\u2019s ideological conflict, there is rarely an effort made to properly address the issues. <\/span>House of M<\/span><\/i> failed Wanda on multiple levels: narratively, because it suggested that for all the crises the world\u2019s mightiest heroes faced, they were helpless to support one of their own; and conceptually, because it places the onus of the fallout on a character who was robbed of her agency.<\/span><\/p>\n

House of M<\/em>\u00a0is a low point for Wanda and how comics deal with the topic of mental illness overall, vilifying a woman\u2019s mental breakdown by having her virtually wipe out a species (one she also belonged to in 2005, mind you) and kill several of her own teammates. The story strips her of her own agency while making her the sole bad guy left to pick up the pieces years later. It\u2019s a story that says the mentally ill are dangerous, that we\u2019re capable of horrible things and maybe we\u00a0should\u00a0be \u201cput down\u201d before those things can happen.<\/span><\/p><\/blockquote>\n

On Queer Superhero A-Listers and a Lack of Visibility<\/span><\/a> (Madeleine Chan, <\/span>AIPT Comics<\/span><\/i>, June 2022)<\/span><\/h2>\n

One of the most notable examples of comic book media to emerge in the pandemic has been the <\/span>Cerebro<\/span><\/i> podcast<\/span><\/a>. Hosted by literary agent Connor Goldsmith, each episode welcomes a guest to talk about the many characters of the X-Men franchise. These discussions often entail a discussion of the queer subtext at work throughout the characters\u2019 histories (since explicit queerness was traditionally taboo in mainstream comics). In the past decade, one of the benefits of the increased push for diverse representation in comics has been increased visibility for queer characters. As Chan notes in this piece, both major and minor characters have been confirmed as queer either by their creators or within their comics \u2014 which raises the question of why there\u2019s been so little effort to do the same for the major characters in their film and television incarnations.<\/span><\/p>\n

But our world is no utopia, and so Chan\u2019s essay raises the issue of how exactly queer characters are being portrayed in their respective comics. They note the cancellation of Al Ewing\u2019s <\/span>Guardians of the Galaxy<\/span><\/i> run, which is interesting not only because it marked the <\/span>second cancellation of a series in which Star-Lord was queer<\/span><\/a>, but because the Guardians\u2019 handling in the comics has been heavily impacted by their portrayal in their movies. With this essay, Chan has exposed yet another display of disingenuity in regard to Marvel and DC\u2019s handling of marginalized characters. Their halfhearted approach to depicting queer characters suggests that their priority is to avoid upsetting intolerant audiences.\u00a0<\/span><\/p>\n

While there is very limited visibility \u2014 Zo\u00eb Kravitz\u2019s Catwoman in <\/span>The Batman<\/span><\/i> was <\/span>played<\/span><\/a> as bisexual and Ryan Reynolds\u2019 Deadpool could be <\/span>interpreted<\/span><\/a> as pansexual \u2014 they still weren\u2019t seen as queer by the larger public. And the queer hints in Wonder Woman 1984 were only <\/span>supposed<\/span><\/a> to be just that, and the odds for Star-Lord to be visible as queer in his upcoming MCU movies is low for <\/span>multiple reasons<\/span><\/a>. It seems DC and Marvel don\u2019t want to risk disrupting the ubiquitously popular mainstream image of these characters to not deter their straight, cisgender male audience. Translations to the screen would be more likely if their queerness was more prominent in the source material.<\/span><\/p><\/blockquote>\n

Monica Rambeau Was\u00a0<\/span>WandaVision<\/span><\/i>‘s Real Hero, and the Show Did Her Dirty<\/span><\/a> (Charles Pulliam-Moore, <\/span>Gizmodo<\/span><\/i>, March 2021)<\/span><\/h2>\n

Many heroes have taken up the mantle of Captain Marvel in the Marvel universe. In the 2019 film about the character, we were introduced to two of them: Carol Danvers, who became closely associated with the role since she took it on in 2012, and Monica Rambeau. If the movie was the extent of your exposure to either character, you might assume that Monica wouldn\u2019t follow in Carol\u2019s footsteps when it came to being a superhero. And you\u2019d have good reason not to, because Monica was actually Carol\u2019s predecessor. <\/span>Introduced as the second Captain Marvel in the same year the original died<\/span><\/a>, she quickly rose to prominence as an Avenger, even becoming the team leader during Roger Stern\u2019s tenure on the book. <\/span>However, she was sidelined soon after losing her powers and relinquishing her title to a newer character that was made to have stronger ties to the original Captain Marvel.\u00a0<\/span><\/a><\/p>\n

Since then, there have been various periods in the comics when Monica struggled to stay afloat appearance-wise. The past decade has seen a renewed effort to return her to the spotlight in titles like <\/span>Ultimates, Damage Control<\/span><\/i>, and her <\/span>upcoming solo series<\/span><\/a>. Unfortunately, her appearances in the Marvel Cinematic Universe so far have failed to capture her might in more ways than one. In this piece, Pulliam-Moore delves into the issues with Monica\u2019s portrayal in her second MCU appearance, 2021\u2019s <\/span>WandaVision<\/span><\/i>. It\u2019s bad enough that Monica has been reduced to playing second fiddle as often as she has, but it\u2019s much more problematic that she\u2019s been portrayed in a way that suggests her heroic nature is heavily influenced by her white peers.<\/span><\/p>\n

While it\u2019s very nice to think that one would choose to be the bigger person after being possessed and attacked by a witch, this characterization for Monica given everything else that happens to her in the series felt like an unnecessary misstep that cast an unignorable shadow over the series as a whole. By not sticking its landing, all of <\/span>WandaVision<\/span><\/i>\u2019s subtle sleights against Monica lose their ability to work as dynamic texture to the story and more like a reminder of how the show missed a choice opportunity to point out how Black sitcoms were huge for a hot second before disappearing almost entirely from network television.<\/span><\/p><\/blockquote>\n

\u2018Into the Spider-Verse\u2019 and the Importance of a Biracial Spider-Man<\/span><\/a> (Richard Newby, <\/span>The Hollywood Reporter<\/span><\/i>, December 2018)<\/span><\/h2>\n

When Stan Lee was asked why Spider-Man (Peter Parker) was one of his favorite characters<\/span><\/a>, he responded that a key factor was Spider-Man\u2019s relatability. \u201cHe\u2019s the one who\u2019s most like me,\u201d he said in an <\/span>interview<\/span><\/a> with the <\/span>Chicago Tribune<\/span><\/i>, \u201che\u2019s got a lot of problems, and he does things wrong and I can relate to that.\u201d This sentiment is likely one that resonated with fans: Spider-Man became one of Marvel\u2019s most popular characters shortly after his 1962 debut. Readers could see themselves in Peter Parker\u2019s everyday struggles when he wasn\u2019t wearing his mask. However, for legions of nonwhite readers, that relatability was only partial \u2014 at least until Miles Morales came along in 2011 to embody Lee\u2019s vision for the rest of the world.<\/span><\/p>\n

For a time, Miles lived in his predecessor\u2019s shadow. Fans knew that he was created in an offshoot universe that allowed creators to be more flexible with Marvel\u2019s iconic heroes. But he rose out of that shadow with the help of his unique powers and distinct background. Standing as his own hero when he was folded into the canonized main comics, Miles\u2019 existence embodies the importance of diverse representation in comic books. Like Captain America\u2019s debut long before him, Miles\u2019 success shows that for all the scrutiny a character may be subject to because of prejudice, there will always be an audience for characters whose identities are treated respectfully on the comic book scene.<\/span><\/p>\n

Miles Morales\u2019 journey to becoming Spider-Man isn\u2019t a straight line. It\u2019s the strands of being black, Latino, a son, a nephew, an honors student, a graffiti artist, a hip-hop fan, all woven together to create the web that is the wide demographic of Spider-Man \u2014 a union of many of the best parts of humanity. There\u2019s a shot in the movie of Miles Morales starring up at a glass display case containing Spider-Man\u2019s uniform. It\u2019s a brief moment without dialogue, but it resonates as one of the film\u2019s most powerful moments because it represents Miles so well, and the tremendous legacy of carrying more than one identity. For all the kids of color who dream of being superheroes, and all the adults of color still grappling with power and responsibility,\u00a0<\/span>Spider-Man: Into the Spider-Verse<\/span><\/i>\u00a0leaves us with a clear message: We could always be Spider-Man with the mask on, but now, and perhaps more important, we can be Spider-Man with the mask off as well.\u00a0<\/span><\/p><\/blockquote>\n

* * *<\/p>\n

Joshua N. Miller is a cultural critic who aims to dissect prevalent social issues through his analysis of comics, film, television, and video games. His writing is available at his website <\/span><\/i>joshuanaimiller.com<\/span><\/i><\/a> and he has content forthcoming in <\/span><\/i>Mangoprism<\/span><\/i><\/a>.\u00a0<\/span><\/i><\/p>\n

Editor: Cheri Lucas Rowlands<\/em><\/p>\n

Copy editor: Peter Rubin<\/em><\/p>\n

 <\/p>\n", + "excerpt": "

The adventures of superheroes reveal a lot about the people who created them \u2014 and the marginalized communities they represent.<\/p>\n", + "slug": "anatomy-of-the-mask-superheroes-comics-reading-list", + "guid": "https:\/\/longreads.com\/?p=159053", + "status": "publish", + "sticky": false, + "password": "", + "parent": false, + "type": "post", + "discussion": { + "comments_open": false, + "comment_status": "closed", + "pings_open": false, + "ping_status": "closed", + "comment_count": 0 + }, + "likes_enabled": true, + "sharing_enabled": true, + "like_count": 106, + "i_like": false, + "is_reblogged": false, + "is_following": false, + "global_ID": "0c80fed92e06e1c094548bf492b3d1d1", + "featured_image": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "post_thumbnail": { + "ID": 159059, + "URL": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "guid": "http:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "mime_type": "image\/jpeg", + "width": 2416, + "height": 1241 + }, + "format": "standard", + "geo": false, + "menu_order": 0, + "page_template": "", + "publicize_URLs": [], + "terms": { + "category": { + "Reading List": { + "ID": 7814148, + "name": "Reading List", + "slug": "reading-list", + "description": "", + "post_count": 655, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Story": { + "ID": 2622, + "name": "Story", + "slug": "story", + "description": "Our Longreads Exclusives and Originals feature some of the best writers and publishers in the world.", + "post_count": 1829, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "post_tag": { + "comics": { + "ID": 756, + "name": "comics", + "slug": "comics", + "description": "", + "post_count": 10, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:comics", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:comics\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "diversity": { + "ID": 47458, + "name": "diversity", + "slug": "diversity", + "description": "", + "post_count": 18, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:diversity", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:diversity\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Marvel": { + "ID": 28454, + "name": "Marvel", + "slug": "marvel", + "description": "", + "post_count": 5, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:marvel", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:marvel\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "representation": { + "ID": 160500, + "name": "representation", + "slug": "representation", + "description": "", + "post_count": 13, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:representation", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:representation\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Spider-Man": { + "ID": 71747, + "name": "Spider-Man", + "slug": "spider-man", + "description": "", + "post_count": 1, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:spider-man", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:spider-man\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "superheroes": { + "ID": 211374, + "name": "superheroes", + "slug": "superheroes", + "description": "", + "post_count": 6, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superheroes", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superheroes\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Superman": { + "ID": 27855, + "name": "Superman", + "slug": "superman", + "description": "", + "post_count": 2, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superman", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superman\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "post_format": {}, + "mentions": {} + }, + "tags": { + "comics": { + "ID": 756, + "name": "comics", + "slug": "comics", + "description": "", + "post_count": 10, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:comics", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:comics\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "comics" + }, + "diversity": { + "ID": 47458, + "name": "diversity", + "slug": "diversity", + "description": "", + "post_count": 18, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:diversity", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:diversity\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "diversity" + }, + "Marvel": { + "ID": 28454, + "name": "Marvel", + "slug": "marvel", + "description": "", + "post_count": 5, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:marvel", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:marvel\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "marvel" + }, + "representation": { + "ID": 160500, + "name": "representation", + "slug": "representation", + "description": "", + "post_count": 13, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:representation", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:representation\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "representation" + }, + "Spider-Man": { + "ID": 71747, + "name": "Spider-Man", + "slug": "spider-man", + "description": "", + "post_count": 1, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:spider-man", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:spider-man\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "spider-man" + }, + "superheroes": { + "ID": 211374, + "name": "superheroes", + "slug": "superheroes", + "description": "", + "post_count": 6, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superheroes", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superheroes\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "superheroes" + }, + "Superman": { + "ID": 27855, + "name": "Superman", + "slug": "superman", + "description": "", + "post_count": 2, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superman", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:superman\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "superman" + } + }, + "categories": { + "Reading List": { + "ID": 7814148, + "name": "Reading List", + "slug": "reading-list", + "description": "", + "post_count": 655, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Story": { + "ID": 2622, + "name": "Story", + "slug": "story", + "description": "Our Longreads Exclusives and Originals feature some of the best writers and publishers in the world.", + "post_count": 1829, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "attachments": { + "159059": { + "ID": 159059, + "URL": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "guid": "http:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "date": "2022-10-19T01:13:51-04:00", + "post_ID": 159053, + "author_ID": 10183950, + "file": "gettyimages-483115783.jpg", + "mime_type": "image\/jpeg", + "extension": "jpg", + "title": "Female superhero face profile", + "caption": "Photo: timoph\/Getty Images", + "description": "Retro masked female hero with long blonde hair, face in profile", + "alt": "Retro masked female hero with long blonde hair, face in profile", + "thumbnails": { + "thumbnail": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=150", + "medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=300", + "large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=1024", + "newspack-article-block-landscape-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=1200&h=900&crop=1", + "newspack-article-block-portrait-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=900&h=1200&crop=1", + "newspack-article-block-square-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=1200&h=1200&crop=1", + "newspack-article-block-landscape-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=800&h=600&crop=1", + "newspack-article-block-portrait-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=600&h=800&crop=1", + "newspack-article-block-square-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=800&h=800&crop=1", + "newspack-article-block-landscape-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=400&h=300&crop=1", + "newspack-article-block-portrait-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=300&h=400&crop=1", + "newspack-article-block-square-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=400&h=400&crop=1", + "newspack-article-block-landscape-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=200&h=150&crop=1", + "newspack-article-block-portrait-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=150&h=200&crop=1", + "newspack-article-block-square-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=200&h=200&crop=1", + "newspack-article-block-uncropped": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg?w=1200" + }, + "height": 1241, + "width": 2416, + "exif": { + "aperture": "0", + "credit": "Getty Images", + "camera": "", + "caption": "Retro masked female hero with long blonde hair, face in profile", + "created_timestamp": "0", + "copyright": "timoph", + "focal_length": "0", + "iso": "0", + "shutter_speed": "0", + "title": "Female superhero face profile", + "orientation": "1", + "keywords": [ + "Beautiful", + "1940-1980 Retro-Styled Imagery", + "Retro Revival", + "Heroes", + "Vector", + "Mid Adult Women", + "Young Women", + "Women", + "Female", + "Illustration and Painting", + "Superhero", + "Pop Art", + "Comic Book", + "Mask", + "Action", + "Determination", + "Motion", + "Red", + "Spotted", + "Close-up", + "Profile View", + "Human Face", + "Human Head", + "Blond Hair", + "Costume", + "Halftone Pattern", + "Action Comics", + "Superwoman" + ] + }, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159059", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159059\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762", + "parent": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159053" + } + } + } + }, + "attachment_count": 1, + "metadata": [ + { + "id": "553326", + "key": "geo_public", + "value": "0" + }, + { + "id": "553339", + "key": "_thumbnail_id", + "value": "159059" + } + ], + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/posts\/159053", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/posts\/159053\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762", + "replies": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159053\/replies\/", + "likes": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159053\/likes\/" + } + }, + "capabilities": { + "publish_post": false, + "delete_post": false, + "edit_post": false + }, + "other_URLs": {}, + "pseudo_ID": "0c80fed92e06e1c094548bf492b3d1d1", + "is_external": false, + "site_name": "Longreads", + "site_URL": "http:\/\/longreads.com", + "site_is_private": false, + "featured_media": { + "uri": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/gettyimages-483115783.jpg", + "width": 2416, + "height": 1241, + "type": "image" + }, + "use_excerpt": false, + "is_following_conversation": false, + "is_subscribed_comments": false, + "can_subscribe_comments": false, + "subscribed_comments_notifications": false + }, + { + "ID": 159026, + "site_ID": 70135762, + "author": { + "ID": 91201193, + "login": "dogtuckerman72", + "email": false, + "name": "Chris Wheatley", + "first_name": "Chris", + "last_name": "Wheatley", + "nice_name": "dogtuckerman72", + "URL": "http:\/\/dogtuckerman72.wordpress.com", + "avatar_URL": "https:\/\/2.gravatar.com\/avatar\/554feecb68c5acd5608cd3af7798e8a5?s=96&d=identicon&r=G", + "profile_URL": "https:\/\/en.gravatar.com\/dogtuckerman72", + "site_ID": 96000669, + "has_avatar": false + }, + "date": "2022-10-18T06:00:28-04:00", + "modified": "2022-10-18T15:40:14-04:00", + "title": "‘This Stuff is Alive’: A Global Folk Music Reading List", + "URL": "http:\/\/longreads.com\/2022\/10\/18\/global-folk-music-reading-list\/", + "short_URL": "https:\/\/wp.me\/p4KhvY-FmW", + "content": "

\r\n

By\u00a0<\/i>Chris Wheatley<\/i><\/a><\/p>\r\n

\u201cI\u2019m not interested in heritage,\u201d said musician Martin Carthy<\/a> on the eve of his 70th birthday. \u201cThis stuff is alive.\u201d With these words, Carthy, a celebrated and driving force in English folk music across several decades, appears to perfectly capture folk\u2019s persistent prominence across the boundaries of language and geography. It is ironic, perhaps, that the genre is often portrayed as outdated, irrelevant, even elitist \u2014 because folk music is, in fact, the antithesis of all these things. It is a living, revolutionary art form documenting the social concerns of humanity, created by the people, for the people.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

But folk music can also be difficult to define. Carthy himself cites African-American blues guitarist Elizabeth Cotton as a major influence. Mongolian band The Hu<\/a> blends the sounds of horsehead fiddle with electric guitars and drums; in Japan, Wagakki Band incorporates the traditional three-stringed shamisen into its blend of heavy rock. This sort of recombinant cross-pollination isn\u2019t new: Since the widespread commercialization of sound recordings began in the early 1900s, arguments around \u201cauthenticity\u201d and the tension between tradition and innovation have raged across numerous cultures. Such debates reached an absurd height during Bob Dylan\u2019s infamous mid-\u201960s tour of the U.K., when an audience member, appalled at the singer\u2019s switch from acoustic to electric instruments, shouted that the musician was \u201cJudas!\u201d<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Martin Carthy himself, who has enjoyed a lengthy and successful career both as a solo artist and as a member of renowned groups Steeleye Span and The Albion Band, is no stranger to blending modern electric instruments with traditional acoustic equipment. Yet the concerns outlined above, as we can see from some of the articles presented below, continue to this day, alongside fears that traditional art forms may die out altogether: abandoned by subsequent generations in favor of newer, shinier sounds; falling foul of commodification; even, in extreme cases, deliberately smothered by political forces.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Which brings us back to the definition of folk music itself. What can we say for sure? \u201cIf\u00a0it was\u00a0never new, and it\u00a0never\u00a0gets\u00a0old,\u00a0then it\u2019s\u00a0a\u00a0folk\u00a0song.\u201d So observes Oscar Isaac\u2019s titular musician in Inside Llewyn Davis<\/i>, the Coen brothers\u2019 cinematic ode to the genre.<\/i> I can think of no better way to describe this music, which continues to bring joy, pride, and hope to millions of listeners around the world.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n

\nArctic Magic<\/a> (Chris Campion, The Guardian<\/i>, January 2007)<\/h2>\r\n\r\n\r\n\r\n

For some time, I have been fascinated by the yoik singing of the Sami people. Native to what is now Northern Finland, Sweden, and Norway, the traditional\u00a0yoik\u00a0song form serves many purposes. It can be an identity marker for individuals living or dead, a tool of communication with animals and nature, even a doorway to other realms. It is an ancient tradition, with roots in prehistoric times<\/a>, but it is only relatively recently that this artform has seemingly been brought back from the edge of extinction.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

To further explore the depth and richness of Sami music, this list of 10 essential albums<\/a>, as presented in Songlines Magazine<\/i>, is a great place to start.<\/blockquote>\r\n\r\n\r\n\r\n

This article by Chris Campion provides a magical peek into the world of the yoik as it is experienced and practiced firsthand, chronicling the efforts of two young Sami determined to preserve and revive their beloved tradition. Happily, in the 15 years since the publication of this piece, yoik appears to have flourished, with several artists and bands recording commercially. Besides the group Adj\u00e1gas, who you will read about in this essay, albums by \u00c1ra, \u00c1\u0161\u0161u,\u00a0<\/i>Marja Mortensson, Hild\u00e1 L\u00e4nsman, and Viivi Maria Saarenkyl\u00e4 have garnered significant acclaim.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\r\n

\u201cSometimes in adjagas I feel that I understand all the world,\u201d says Sara. \u201cI understand all the questions that I sometimes wonder about. You feel that and then you are really open for these yoiks to come. If I couldn\u2019t yoik, I think I would die.\u201d<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n

\nDesert Blues | The Music Moves in Circles<\/a> (Randall Grass, Kosmos Journal<\/i>, Fall 2022)<\/h2>\r\n\r\n\r\n\r\n\r\n\r\n

Blues music\u2019s standard 12-bar chord progression, which most experts agree developed from African American slave work songs and spirituals, underpins almost all Western popular music. What an absolute delight it is, then, to see the blues travel full circle, exported back to the country of its ancestry, reclaimed, repurposed, and revitalized. So-called \u201cdesert blues,\u201d emanating from Africa\u2019s Saharan region, has been steadily growing in popularity over the last 20 years, driven by the band Tinariwen, whose founding members first united while in exile in Algeria.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Tinariwen blends electric guitars with traditional instruments to create a beguiling blanket of sound that encapsulates the majesty and stark beauty of the Sahara, and their commercial success opened the door to a wave of like-minded musicians. The interaction between \u201cWestern\u201d blues and the African continent, however, goes back much further, as explored in this fascinating piece by Randall Grass, in which the author recounts his experiences with local musicians while living in Kano, Nigeria, during the mid-\u201970s.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\r\n

Afterwards, I shared a beer with Alhaji Liu in a little bar. As we talked, via a translator due to my limited Hausa, an Albert King blues song played over the bar\u2019s sound-system. \u201cI can play that,\u201d Alhaji Liu said. That was my introduction to what has often been labeled \u201cdesert blues.\u201d<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n

\nHarry Smith\u2019s Musical Catalogue of Human Experience<\/a> (Amanda Petrusich, The New Yorker<\/i>, September 2020)<\/h2>\r\n\r\n\r\n\r\n\r\n\r\n

It is difficult to name a record (or records) more influential than Harry Smith\u2019s Anthology of American Folk Music<\/i>, which served as a virtual bible for \u201950s and \u201960s folk revivalists, Bob Dylan among them. Comprising recordings bought and selected by Harry Smith himself, this three-LP collection still stands as a cornerstone of Western popular music, and yet its genesis and rise to prominence form one of the strangest and most inscrutable tales in music history.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

You can read more about the anthology, and listen to its contents, at the official Smithsonian Folkways online catalogue<\/a>. For more information on Smith himself, the Harry Smith Online Archive<\/a> provides an exhaustive overview of \u201cone of the least understood figures in post-war American Culture.\u201d<\/blockquote>\r\n\r\n\r\n\r\n

Central to this story is the wonderfully bizarre figure of Smith himself. A bohemian outlier with esoteric tastes, including a passion for magic and alchemy, he was only in his early twenties when he put together his \u201canthology.\u201d A practicing member of The Ecclesia Gnostica Catholica (a church founded by the infamous occultist and \u201cmagician\u201d Aleister Crowley), Smith held a predilection for the arcane, as evidenced by some of the wilder cuts included in this set. Bascom Lamar Lunsford\u2019s \u201cI Wish I Was a Mole in the Ground\u201d and Chubby Parker\u2019s \u201cKing Kong Kitchie Kitchie Ki-Me-O\u201d are both fine examples.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

In this fantastic essay, Amanda Petrusich explains exactly why this \u201cstrange cosmology of music\u201d continues to enjoy reverential status.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\r\n

Once, in a strange fury of obsession, I spent several months on the lower level of the New York Public Library for the Performing Arts, trying to track down Smith\u2019s own 78s, some of which he had sold to the library before he died. Smith believed that objects have power; I thought there might be something to learn from holding those records in my hands.<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n

\nA Revival of Indigenous Throat Singing<\/a> (Joel Balsam and Stephanie Foden, BBC<\/i>, April 2021)<\/h2>\r\n\r\n\r\n\r\n\r\n\r\n

The particular strength of folk song is that it intrinsically belongs to its people. The music unites communities, entertains them, and documents their loves, losses, and struggles. It\u2019s a genre that has long been used to stir passions, swell pride, and resist injustice and oppression. Little wonder, then, that colonialists and dictators the world over have routinely sought to curtail, or even extinguish, the traditional music of the land. Folk music provides identity and hope, not least in the extraordinarily intimate tradition of Inuit throat singing.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

In the early 20th century, Christian missionaries in the Arctic branded the music as blasphemous, even Satanic, in nature \u2014 and throat singing all but died out. This moving article by Joel Balsam and Stephanie Foden follows Shina Novalinga and her mother, Caroline, as they fight to reinvigorate the tradition via the distinctly modern means of social media.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\r\n

In March 2020, when the first wave of the pandemic hit Montreal, Shina started sharing throat singing videos on TikTok. The videos also showcased the gorgeous handmade parkas<\/a> sewn and designed by her mother along with facts about Indigenous history. \u201cFor me it\u2019s so normal, but I realised how unique it is for everyone to hear that, and even just different aspects of our culture, our food, our clothing,\u201d Shina said.<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n

\nRhythm in Your Blood: Meet the Young Artists Keeping Cuba\u2019s Traditional Music Alive<\/a> (Marisa Aveling, Pitchfork<\/i>, June 2016)<\/h2>\r\n\r\n\r\n\r\n\r\n\r\n

Cuba occupies a special place in music history. Partly thanks to its unique blend of Spanish, African, and Caribbean music, the island\u2019s creative influence extends across the globe, feeding numerous genres from jazz and rock to ballroom dance, classical, and even hip-hop. The spectacular success of the album Buena Vista Social Club <\/i>and its accompanying documentary film, both of which showcased some of the best of the country\u2019s talent in the mid-\u201990s, brought Cuban music to a new generation \u2014 but much remains to explore.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

For more on the Buena Vista Social Club, including a full history, list of musicians involved and video clips, visit the project\u2019s official website<\/a>.<\/blockquote>\r\n\r\n\r\n\r\n

Ironically, Cuba\u2019s vibrant traditional music scene may well have thrived within its borders in part thanks to its relative isolation from the outside world. However, with the country appearing to gradually temper its hard-line stance, that relaxation may catalyze change. As Marisa Aveling observes in this fascinating piece, some are concerned that, new freedoms and visions \u2014 not to mention alien influences \u2014 may well distract young people away from their historic art forms. Enter the Manana music festival, the first such international event to take place on the island, and one aimed squarely at preserving and developing Cuban sounds.<\/p>\r\n\r\n\r\n\r\n

\r\n

\u201cIt\u2019s an expression of Cuban style,\u201d says Geovani del Pino, the 73-year-old director of Yoruba Andabo<\/a>, the Latin Grammy-winning 15-piece band that has been fundamental in representing rumba internationally. \u201cI don\u2019t think that someone who calls themselves Cuban feels a conga without his feet moving.\u201d<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n

\nGriot on Wheels<\/a> (Joseph McLellan, The Washington Post<\/i>, May 1978)<\/h2>\r\n\r\n\r\n\r\n\r\n\r\n

Almost every civilization, it seems, has its version of the West African griots: itinerant musicians and orators, revered for both their skills and the vital role they play in preserving history and continuing traditions. Celtic cultures had ancient bards; Vikings had their skalds; classical Greece, its rhapsodes. Griots, however, still form an integral part of contemporary societies from Senegal and Mauritania to Nigeria and Mali, serving as living libraries, genealogists, entertainers, and ceremonial functionaries.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

In this beautiful piece from 1978, Joseph McLellan talks to Batourou Sekou Kouyate, a griot from Bamko, Mali, as he tours America in an old station wagon, making new friends, new connections, and speaking with passion about the ancient craft of his art.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\r\n

\u201cIn my country,\u201d he said in an interview at the Museum of African Art, \u201cI can go with my kora to anyone\u2019s house and say, \u201cI want you to help me,\u2019 and with three wives and 10 children, I could move into that house and spend my whole life there, and when I die my children could stay there after me. That is what we call nobility.\u201d<\/p>\r\n<\/blockquote>\r\n

***<\/p>\r\n

Chris Wheatley<\/a>\u00a0is a writer and journalist based in Oxford, UK. He has too many guitars, too many records, and not enough cats.<\/em><\/p>\r\n

Editor:\u00a0Peter Rubin<\/a>
<\/em>Copy Editor:\u00a0
Krista Stevens<\/a><\/em><\/p>\r\n <\/div>", + "excerpt": "

Six pieces that demonstrate the timelessness of ever-changing sonic traditions.<\/p>\n", + "slug": "global-folk-music-reading-list", + "guid": "http:\/\/longreads.com\/?p=159026", + "status": "publish", + "sticky": false, + "password": "", + "parent": false, + "type": "post", + "discussion": { + "comments_open": false, + "comment_status": "closed", + "pings_open": false, + "ping_status": "closed", + "comment_count": 0 + }, + "likes_enabled": true, + "sharing_enabled": true, + "like_count": 79, + "i_like": false, + "is_reblogged": false, + "is_following": false, + "global_ID": "1fa06ae0a42ec73c76f79c1f9faabaae", + "featured_image": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "post_thumbnail": { + "ID": 159048, + "URL": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "guid": "http:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "mime_type": "image\/png", + "width": 2000, + "height": 1600 + }, + "format": "standard", + "geo": false, + "menu_order": 0, + "page_template": "", + "publicize_URLs": [], + "terms": { + "category": { + "Arts & Culture": { + "ID": 74554, + "name": "Arts & Culture", + "slug": "arts-culture", + "description": "", + "post_count": 743, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:arts-culture", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:arts-culture\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Featured": { + "ID": 35890, + "name": "Featured", + "slug": "featured", + "description": "", + "post_count": 1613, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:featured", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:featured\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Reading List": { + "ID": 7814148, + "name": "Reading List", + "slug": "reading-list", + "description": "", + "post_count": 655, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Story": { + "ID": 2622, + "name": "Story", + "slug": "story", + "description": "Our Longreads Exclusives and Originals feature some of the best writers and publishers in the world.", + "post_count": 1829, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "post_tag": { + "BBC": { + "ID": 2988, + "name": "BBC", + "slug": "bbc", + "description": "", + "post_count": 24, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:bbc", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:bbc\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "blues": { + "ID": 1430, + "name": "blues", + "slug": "blues", + "description": "", + "post_count": 17, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:blues", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:blues\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "folk music": { + "ID": 20421, + "name": "folk music", + "slug": "folk-music", + "description": "", + "post_count": 8, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:folk-music", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:folk-music\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "indigenous peoples": { + "ID": 194123, + "name": "indigenous peoples", + "slug": "indigenous-peoples", + "description": "", + "post_count": 9, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:indigenous-peoples", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:indigenous-peoples\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Kosmos Journal": { + "ID": 13446526, + "name": "Kosmos Journal", + "slug": "kosmos-journal", + "description": "", + "post_count": 1, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:kosmos-journal", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:kosmos-journal\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "music": { + "ID": 18, + "name": "music", + "slug": "music", + "description": "", + "post_count": 226, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:music", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:music\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Pitchfork": { + "ID": 316996, + "name": "Pitchfork", + "slug": "pitchfork", + "description": "", + "post_count": 16, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:pitchfork", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:pitchfork\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "The Guardian": { + "ID": 97838, + "name": "The Guardian", + "slug": "the-guardian", + "description": "", + "post_count": 152, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-guardian", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-guardian\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "The Washington Post": { + "ID": 186133, + "name": "The Washington Post", + "slug": "the-washington-post", + "description": "", + "post_count": 45, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-washington-post", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-washington-post\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "post_format": {}, + "mentions": {} + }, + "tags": { + "BBC": { + "ID": 2988, + "name": "BBC", + "slug": "bbc", + "description": "", + "post_count": 24, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:bbc", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:bbc\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "bbc" + }, + "blues": { + "ID": 1430, + "name": "blues", + "slug": "blues", + "description": "", + "post_count": 17, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:blues", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:blues\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "blues" + }, + "folk music": { + "ID": 20421, + "name": "folk music", + "slug": "folk-music", + "description": "", + "post_count": 8, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:folk-music", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:folk-music\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "folk-music" + }, + "indigenous peoples": { + "ID": 194123, + "name": "indigenous peoples", + "slug": "indigenous-peoples", + "description": "", + "post_count": 9, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:indigenous-peoples", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:indigenous-peoples\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "indigenous-peoples" + }, + "Kosmos Journal": { + "ID": 13446526, + "name": "Kosmos Journal", + "slug": "kosmos-journal", + "description": "", + "post_count": 1, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:kosmos-journal", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:kosmos-journal\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "kosmos-journal" + }, + "music": { + "ID": 18, + "name": "music", + "slug": "music", + "description": "", + "post_count": 226, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:music", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:music\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "music" + }, + "Pitchfork": { + "ID": 316996, + "name": "Pitchfork", + "slug": "pitchfork", + "description": "", + "post_count": 16, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:pitchfork", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:pitchfork\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "pitchfork" + }, + "The Guardian": { + "ID": 97838, + "name": "The Guardian", + "slug": "the-guardian", + "description": "", + "post_count": 152, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-guardian", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-guardian\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "the-guardian" + }, + "The Washington Post": { + "ID": 186133, + "name": "The Washington Post", + "slug": "the-washington-post", + "description": "", + "post_count": 45, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-washington-post", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/tags\/slug:the-washington-post\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + }, + "display_name": "the-washington-post" + } + }, + "categories": { + "Arts & Culture": { + "ID": 74554, + "name": "Arts & Culture", + "slug": "arts-culture", + "description": "", + "post_count": 743, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:arts-culture", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:arts-culture\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Featured": { + "ID": 35890, + "name": "Featured", + "slug": "featured", + "description": "", + "post_count": 1613, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:featured", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:featured\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Reading List": { + "ID": 7814148, + "name": "Reading List", + "slug": "reading-list", + "description": "", + "post_count": 655, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:reading-list\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + }, + "Story": { + "ID": 2622, + "name": "Story", + "slug": "story", + "description": "Our Longreads Exclusives and Originals feature some of the best writers and publishers in the world.", + "post_count": 1829, + "parent": 0, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/categories\/slug:story\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762" + } + } + } + }, + "attachments": { + "159048": { + "ID": 159048, + "URL": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "guid": "http:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "date": "2022-10-17T15:48:54-04:00", + "post_ID": 159026, + "author_ID": 132359147, + "file": "global-folk-music-1-1.png", + "mime_type": "image\/png", + "extension": "png", + "title": "Global Folk Music (1)", + "caption": "Clockwise from top left: Finnish singer Marja Mortensson; a Tuvan throat singer; Galbadrakh \"Gala\" Tsendbaatar of Mongolian folk-metal band The Hu; Said Ag Ayad of Tuareg ensemble Tinariwen. (Photos: Getty Images)", + "description": "", + "alt": "A collage of global folk musicians \u2014 from Finland, Tibet, Mongolia, and Mali \u2014 all performing in traditional dress.", + "thumbnails": { + "thumbnail": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=150", + "medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=300", + "large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=1024", + "newspack-article-block-landscape-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=1200&h=900&crop=1", + "newspack-article-block-portrait-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=900&h=1200&crop=1", + "newspack-article-block-square-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=1200&h=1200&crop=1", + "newspack-article-block-landscape-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=800&h=600&crop=1", + "newspack-article-block-portrait-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=600&h=800&crop=1", + "newspack-article-block-square-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=800&h=800&crop=1", + "newspack-article-block-landscape-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=400&h=300&crop=1", + "newspack-article-block-portrait-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=300&h=400&crop=1", + "newspack-article-block-square-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=400&h=400&crop=1", + "newspack-article-block-landscape-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=200&h=150&crop=1", + "newspack-article-block-portrait-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=150&h=200&crop=1", + "newspack-article-block-square-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=200&h=200&crop=1", + "newspack-article-block-uncropped": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png?w=1200" + }, + "height": 1600, + "width": 2000, + "exif": { + "aperture": "0", + "credit": "", + "camera": "", + "caption": "", + "created_timestamp": "0", + "copyright": "", + "focal_length": "0", + "iso": "0", + "shutter_speed": "0", + "title": "", + "orientation": "0", + "keywords": [] + }, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159048", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159048\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762", + "parent": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159026" + } + } + }, + "159037": { + "ID": 159037, + "URL": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png", + "guid": "http:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png", + "date": "2022-10-17T15:07:24-04:00", + "post_ID": 159026, + "author_ID": 132359147, + "file": "global-folk-music.png", + "mime_type": "image\/png", + "extension": "png", + "title": "Global Folk Music", + "caption": "Clockwise from top left: Finnish singer Marja Mortensson; a Tuvan throat singer; Galbadrakh \"Gala\" Tsendbaatar of Mongolian folk-metal band The Hu; Said Ag Ayad of Tuareg ensemble Tinariwen. (Photos: Getty Images)", + "description": "", + "alt": "A collage of global folk musicians \u2014 from Finland, Tibet, Mongolia, and Mali \u2014 all performing in traditional dress.", + "thumbnails": { + "thumbnail": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=150", + "medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=300", + "large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=1024", + "newspack-article-block-landscape-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=1200&h=900&crop=1", + "newspack-article-block-portrait-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=900&h=1200&crop=1", + "newspack-article-block-square-large": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=1200&h=1200&crop=1", + "newspack-article-block-landscape-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=800&h=600&crop=1", + "newspack-article-block-portrait-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=600&h=800&crop=1", + "newspack-article-block-square-medium": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=800&h=800&crop=1", + "newspack-article-block-landscape-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=400&h=300&crop=1", + "newspack-article-block-portrait-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=300&h=400&crop=1", + "newspack-article-block-square-small": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=400&h=400&crop=1", + "newspack-article-block-landscape-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=200&h=150&crop=1", + "newspack-article-block-portrait-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=150&h=200&crop=1", + "newspack-article-block-square-tiny": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=200&h=200&crop=1", + "newspack-article-block-uncropped": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music.png?w=1200" + }, + "height": 1600, + "width": 2000, + "exif": { + "aperture": "0", + "credit": "", + "camera": "", + "caption": "", + "created_timestamp": "0", + "copyright": "", + "focal_length": "0", + "iso": "0", + "shutter_speed": "0", + "title": "", + "orientation": "0", + "keywords": [] + }, + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159037", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/media\/159037\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762", + "parent": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159026" + } + } + } + }, + "attachment_count": 2, + "metadata": [ + { + "id": "553284", + "key": "geo_public", + "value": "0" + }, + { + "id": "553310", + "key": "_thumbnail_id", + "value": "159048" + } + ], + "meta": { + "links": { + "self": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/posts\/159026", + "help": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762\/posts\/159026\/help", + "site": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/read\/sites\/70135762", + "replies": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159026\/replies\/", + "likes": "https:\/\/public-api.wordpress.com\/rest\/v1.1\/sites\/70135762\/posts\/159026\/likes\/" + } + }, + "capabilities": { + "publish_post": false, + "delete_post": false, + "edit_post": false + }, + "other_URLs": {}, + "pseudo_ID": "1fa06ae0a42ec73c76f79c1f9faabaae", + "is_external": false, + "site_name": "Longreads", + "site_URL": "http:\/\/longreads.com", + "site_is_private": false, + "featured_media": { + "uri": "https:\/\/longreadsblog.files.wordpress.com\/2022\/10\/global-folk-music-1-1.png", + "width": 2000, + "height": 1600, + "type": "image" + }, + "use_excerpt": false, + "is_following_conversation": false, + "is_subscribed_comments": false, + "can_subscribe_comments": false, + "subscribed_comments_notifications": false + }, + { + "ID": 159011, + "site_ID": 70135762, + "author": { + "ID": 17355290, + "login": "bromeara8", + "email": false, + "name": "Brendan O'Meara", + "first_name": "Brendan", + "last_name": "O'Meara", + "nice_name": "bromeara8", + "URL": "http:\/\/breakingbat.wordpress.com", + "avatar_URL": "https:\/\/0.gravatar.com\/avatar\/6cdef29271031bbfd2ee3c6b355611d6?s=96&d=identicon&r=G", + "profile_URL": "https:\/\/en.gravatar.com\/bromeara8", + "site_ID": 42425048, + "has_avatar": true + }, + "date": "2022-10-17T06:00:15-04:00", + "modified": "2022-10-15T12:05:21-04:00", + "title": "The Rhythm of Writing: A Chat with the Writer and Editor Behind The Atavist\u2019s New Issue", + "URL": "http:\/\/longreads.com\/2022\/10\/17\/the-rhythm-of-writing-a-chat-with-the-writing-and-editor-behind-the-atavists-new-issue\/", + "short_URL": "https:\/\/wp.me\/p4KhvY-FmH", + "content": "

\r\n

As host of <\/i>The Creative Nonfiction Podcast, Brendan O\u2019Meara is no stranger to talking about the art and craft of storytelling. In this craft-focused excerpt, we\u2019re digging into Episode 336<\/a>, in which he interviewed <\/i>Atavist editor Jonah Ogles and freelance writer Cassidy Randall about her work on the latest issue of <\/i>The Atavist.<\/i><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Cassidy Randall, a freelance writer based out of Montana, sees herself more as a writer than a reporter, or a writer first<\/i> then a reporter. There isn\u2019t any question she can report, as evidenced by her Atavist Magazine <\/i>piece \u201cAlone at the Edge of the World<\/a>,\u201d but take a look at this opening sentence \u2014 read it aloud \u2014 and you will hear<\/i> a writer at work:<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\u201cIn the heaving seas of the Southern Ocean, a small, red-hulled sailboat tossed and rolled, at the mercy of the tail end of a tempest.\u201d<\/i><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

The alliteration is beautifully embedded in this 25-word sentence.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\u201cI love rhythm in sentences,\u201d Randall says. \u201cOne of the reasons I had chosen some of those longer sentences was that I wanted it to feel dreamlike, so that you have a long time to be in this moment.\u201d<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Randall\u2019s story charts the story of Susie Goodall as she competed in the Golden Globe Race, a race to sail solo around the world. By this piece\u2019s very nature (Randall was not in the boat with Goodall), it\u2019s a masterclass in recreating scenes, something vital to this kind of storytelling.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

\u201cI like to spend a lot of time saying, \u2018Tell me what happens. Do you remember this?\u2019 And if there\u2019s a detail that I want to hear about that maybe gets a little glossed over, I always make time to go back. I\u2019m constantly writing these notes that say, \u2018Go back to this one thing. What was this? Be sure to follow up on this.\u2019 And so it\u2019s just a series of questions.\u201d<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Randall also digs into how she deals \u2014 or doesn\u2019t deal \u2014 with rejection, as well as myriad other struggles common to the freelance-writer experience.<\/p>\r\n\r\n\r\n\r\n

Please enjoy this excerpt below, and listen to the full episode<\/a> for more.<\/p>\r\n\r\n\r\n\r\n

These interviews have been edited for clarity and concision.<\/i><\/p>\r\n\r\n\r\n\r\n

* * *<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Brendan O\u2019Meara: If I had a harrowing boat-journey story, should I turn to you to edit it?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Jonah Ogles, Atavist<\/em> articles editor: <\/b>The answer is, you should turn to Cassidy to write it. Man, she nailed this story, it was so much fun to work on. She had a really good handle on her character, and clearly knew what she was doing when it comes to adventure writing. Yes, the writing is good, but I\u2019m talking about pure narrative, the arc of the story itself \u2014 Susie Goodall\u2019s experience. When you get something like this, you just let it do its job. You tell the story, and you get out of the way, except for the parts where you absolutely need to be there.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

One of the more chilling aspects of the story is that you really feel like you\u2019re in the boat with Susie, and you feel the power and terror of this wave. When I spoke with Cassidy, she said that in an earlier draft there\u2019s \u2014 not a set piece, but several paragraphs explaining rogue waves, which sounds fascinating. But to your point, it might have been a little hiccup among what were already very good story blocks.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

This is a story where we cut things \u2014 not because they were bad, but because Susie\u2019s story on its own was so good. Rogue waves are a fascinating phenomenon, and especially when it comes into play in this story, because statistically speaking it shouldn\u2019t have occurred during this race.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Cassidy had all this really fascinating stuff about rogue waves and the scientific consensus about whether they\u2019re predictable in some way. The problem is, it happened during the storm, when Susie is out there on her own. As a reader, I\u2019m already there. I\u2019m invested. If you\u2019re watching a movie, it\u2019s like reaching the climax, and then stepping away for a second to have some narrator speak to you about the context of the scene. That\u2019s fine, but what we want to know is, is the dude going to fire the gun or not?<\/i><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

The peril of nonfiction in so many ways.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I do this a lot: When I\u2019m cutting early in a piece I\u2019ll say, \u201cthere may be a place for this later in this particular story.\u201d We didn\u2019t end up reinserting it but there were other things that we did find a home for elsewhere. But in that moment, I just didn\u2019t. And this is maybe selfish because as a reader, I just didn\u2019t want to be away from Susie and her experience.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

We often talk about how these Atavist<\/i> stories are puzzle-like in nature. What were some of the challenges that were unique to this piece as you were bringing it to life?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

This was less of an editing challenge than a challenge for Cassidy, although she really pulled it off: The majority of the words occur with Susie alone on a boat. It\u2019s like that Robert Redford movie Alone<\/i>, where he\u2019s sailing alone on a boat, and there\u2019s virtually no dialogue. That\u2019s a difficult thing to do. How do you write thousands of miles of solo sailing, which includes periods of time in which nothing happens? How do you make readers feel close to this character when you don\u2019t really get to see her interact with anyone else? You have to be really deep inside Susie\u2019s head. Originally, Cassie had these snippets: Here\u2019s 200 words about marine wildlife she saw; here\u2019s 400 words about this piece of equipment malfunctioning. All of it has value and lets you know Susie in different ways, but as a reader it felt like getting postcards from somebody on a trip. \u201cHaving fun, had a good dinner.\u201d It was hard to feel like you were on the boat with her. So we tried to streamline.<\/p>\r\n

Another challenge was that her family becomes very concerned for her once she goes through the storm. After something like 12,000 words next to Susie, all of a sudden we need to be away from Susie to experience what\u2019s happening outside of her little bubble. So it was really a trial and error situation: Let\u2019s try dropping in with her family right here<\/i>, and let\u2019s try 400 words. How does that feel? Not quite right. Let\u2019s move it, let\u2019s shorten it up, let\u2019s lengthen it. And we just did that until it felt like we\u2019d gotten it to a point where you\u2019re never away from Susie so long that you\u2019ve forgotten where you are in the narrative. But you\u2019re with the family long enough that there\u2019s some emotional resonance with them as well. You\u2019re not just hearing what they feel; you feel it too.<\/p>\r\n


\n

Kickstart your weekend reading by getting the week\u2019s best Longreads delivered to your inbox every Friday afternoon.<\/p>\r\n

Sign up<\/a><\/p>\r\n


\n

You said this was one of the more fun stories that you\u2019ve been able to work on. What makes a story fun for you as an editor?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I\u2019m still totally an Outside <\/i>magazine guy at heart. I like adventure stories and survival stories and feats of human endurance. It checked that box for me naturally. Originally, Seyward [Darby, The Atavist <\/i>editor in chief] was going to run lead on this, but I\u2019m really glad it worked out that I got to jump in.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Cassidy had strong opinions about what she wanted the piece to do, but was also very happy to collaborate and listen to differences of opinion, so it felt like we were always pushing the story forward in a good way. But part of it, too, is that Susie is just a really interesting character. She\u2019s not only doing this interesting thing, but she has an interesting perspective on it. And maybe this is another testament to Cassidy, but it seemed like they really had a good connection, and that Cassidy had a good sense of how to convey Susie\u2019s thoughts and experiences in the story. \u201cCan you get us closer to this character?\u201d was never a note I had to give during this story; we were just close to her from the beginning.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

* * *<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Cassidy, what are some of the inspirations that you draw from so you can synthesize pieces of this nature?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Cassidy Randall: <\/b>In preparing for this piece, I actually read some sailing books. The Long Way<\/i> by Bernard Moitessier about his journey in the Golden Globe<\/a>. So many of the other competitors in that original Golden Globe were having a horrific time with loneliness and leaking boats and weather and dealing with a lot of mental stuff \u2014 and he was just gazing at the Aurora and watching dolphins frolic. I also read Voyage for Madmen<\/i> by Peter Nichols, which also chronicles the logs of those sailors in the original Golden Globe, and is a pretty propulsive read. If you\u2019re a sailor, he uses a lot of sailing terminology that ocean people absolutely love. But if you\u2019re not a sailor, it might be kind of harder to get through that.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I wish I could write fiction, honestly. I have trouble personally getting through a lot of nonfiction books, so to ask what influenced me in writing this, I would just list fiction book after fiction book. It\u2019s like my entire upbringing of reading to figure out how to weave together several different arcs into a single \u2026 arc, for lack of a better non-repetitive word.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

What novels or short stories do you return to again and again?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I\u2019m rereading some Louise Erdrich. I just think that her books are just incredible. She came to speak in Missoula recently. I reread Lonesome Dove<\/i> by Larry McMurtry recently. Holy moly, what a tour de force; that\u2019s an incredible one.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Your Instagram bio just says, \u201cwriting stories on environment, adventure, and people exploring the bounds of human potential.\u201d And I was like, \u201cwell, that about sums up her Atavist<\/i> story.\u201d<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

So true.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

How did you arrive at it?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

My family is a family of sailors. I\u2019ve never been able to get into bluewater sailing \u2014 I love the mountains, I love skiing \u2014 but my sister is an avid sailor, my dad taught us how to sail, my uncle\u2019s a sailor. I had a friend who was following Susie Goodall around the time the Golden Globe was coming back, and that introduced the story to me. I pitched it around; my Time<\/i> editor had really wanted a story on the race, but we couldn\u2019t fit it in. When Susie pitchpoled, I ended up reporting about that for Adventure Journal<\/i>. And then I had written about Jean-Luc Van Den Heede for Men\u2019s Journal<\/i>. So I was familiar with the race. And in reporting that story on Susie, I had noticed that she never really talked to anybody. When she got back, no news outlets had anything beyond her statement, which I thought was really interesting.<\/p>\r\n\r\n

The podcast 59 North<\/i> is now known as On the Wind<\/i><\/a>.<\/blockquote>\r\n

I reached out to her last year, because I was thinking about writing a book on women and sailing. I had no idea that she would check this email that goes through her website, but I sent a note saying that I was really compelled by her journey, that I\u2019d heard her talk about it on this podcast called 59 North<\/i>, and that I\u2019d love to just talk to her and see where she was in life now. We had a lot of conversations before she agreed to work on a story with me. We built up a lot of trust together, I think because she\u2019d had some bad experiences with the way that her story was told.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

As your story illustrates, Susie was dangled out in front as the lone woman in the race, and it ended up being a real study in gender and media. When you were getting that trust that you mentioned, how did you gain her confidence to be able to tell her story in a way that honored her place in the Golden Globe?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I think that\u2019s almost something to ask Susie, but I actually did ask her that, too, towards the end. She said she liked that I didn\u2019t have some pre-thought-out narrative in mind \u2014 that I wanted to hear everything that she had to say, essentially. Even as I was formulating some of these arcs, I would run things past her, like \u201cDoes this seem like what you were actually feeling?\u201d So much of the story, it feels like you\u2019re in her head, and that\u2019s a huge responsibility. I think the fact that I was really collaborative with her even after we\u2019d had hours upon hours of conversations, I think that that made her feel more at ease, too.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

The real challenge in third-person nonfiction is to get in the head of your principal figure. As a reporter, how did you go about interviewing her so that you were getting between her ears?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I wanted to know so much about her background. I mean, we spent so much time talking about just the prep for a voyage like this before we even got into setting off. I wanted to know about her love of sailing, how the ocean had obsessed her, and maybe that helped a bit with building trust. I\u2019ve only done one blue water crossing ever, but I could at least understand the pull of the ocean. And so I asked her a lot about that.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I always want to know how something feels in someone\u2019s body when they\u2019re scared or when they\u2019re thrilled. I want to know how those emotions feel, and where people feel them. She had this beautiful way of talking about celestial navigation, where she talked about how some sailors used to be so in tune with the ocean that it would speak to them, that before compasses Vikings would mark where on the horizon the sun rose, or how Polynesians knew which direction they were going just based on swells and currents. That\u2019s how we got into the fact that she had read all of these books, and how the books had influenced so much of why she wanted to sail solo and find this connection.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

But the other thing is that I just love to let a subject go on. I don\u2019t like to interrupt, and I often find that people will go in the best directions when they\u2019re just allowed to talk.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Robert Caro famously wrote in the margins in his notebooks, SU SU \u2014 as in, \u201cshut up, shut up\u201d \u2014 anytime he was interviewing a source, be it for his Robert Moses biography any of his volumes of Lyndon Johnson. Oftentimes reporters and writers want to interject to prove how smart they are, prove how much they know. But oftentimes, the best interviewing tactic you can do is to just shut up. Silence can do a lot of the heavy lifting.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Oh my gosh, absolutely. Sometimes thoughts take a while to process, and a lot of people have never been interviewed. I mean, Susie obviously had quite a lot, but I don\u2019t know how much people had given her space to actually speak, either, because I think a lot of things were time-sensitive. A lot of us in general aren\u2019t used to being listened to, and by asking the next question we might cut something off that hasn\u2019t been fully formed. You have no idea what could possibly come out when somebody fully processes a question that you\u2019ve asked. I think that\u2019s really fascinating.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

This story is really a masterclass in recreating scenes; you weren\u2019t in the boat with her, but it felt that way. Let\u2019s talk about how you went about getting that degree of recreation.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I think that also comes from having enough time to speak to somebody that you can say, \u201cwalk me through what happened.\u201d You\u2019re not always lucky enough to be writing with or about somebody who remembers so much. And honestly, if she hadn\u2019t written down what happened to her during the wave, she might not remember either. But she did remember so much of the actual voyage and the prep, which is incredible.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

But I also think that since I\u2019ve been in a small sailboat, I\u2019ve experienced some things that are similar to what Susie experienced in different mediums. Like, I\u2019ve felt my stomach drop like that before \u2014 not because I\u2019ve been involved in an 80-foot wave, but it helps to be able to run that past somebody and say, \u201cdoes this translate?\u201d<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

One particularly chilling scene was when she\u2019s in the middle of a storm, then all of a sudden it goes quiet \u2014 because a giant wave that is approaching is blocking all the sounds. How do you even begin to build a scene like that?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

This is almost exactly how she described it to me in the lead-up to that moment. She remembers exactly how that felt, that moment when she thought that someone had turned the wind off \u2014 and then had this feeling of no, no, no, no<\/i>. It\u2019s like gold for writers when somebody remembers something like that. That\u2019s like a privilege. Jim Harrison talked about how he wrote Legends of the Fall<\/i> in nine days, and it was like taking dictation from the gods. If you\u2019re a nonfiction writer, when you have a source like this, and somebody who\u2019s willing to talk about it like that, it is like taking dictation. It\u2019s incredible.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

What do you think it is about long journeys \u2014 be it the Pacific Crest Trail or circumnavigating the globe \u2014 that draws us to them, and that we find so much meaning in?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I mean, I think that we evolved with the natural world. And we\u2019ve been so removed from it in such a geologically short timespan that I think we mourn that in a lot of ways. That\u2019s often what people are seeking when we head out into the woods, the ocean, the mountains: it\u2019s where we feel more alive. When you talk to people, particularly in adventure sports, there\u2019s this thin line between life and death, and proximity to the elements brings us so much closer. I think that\u2019s a morbid way to put it, but it\u2019s this idea that we\u2019re part of something bigger \u2014 and we aren\u2019t at the top of this bigger thing.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Well, there\u2019s an element of our modern lifestyle that\u2019s very sedentary. We fall into very grooves of our everyday routines, and it\u2019s very hard to break out of that and to find comfort in discomfort. It\u2019s at our core to be able to push our physical limits, but there\u2019s a lot pulling at us not<\/i> to do that, be it social media or television. As an outdoor person, how do you try to make a good partnership with discomfort?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I\u2019ve made it a priority to live somewhere where I have access to less development. There\u2019s wilderness a mile up the road, but of course, these things are disappearing very quickly, too. I think it\u2019s a conscious thing that we have to make time to go out and be far away from cell service, which also is harder and harder to do these days. For our honeymoon \u2014 and most people would think this was horrible \u2014 my husband and I walked across the Bob Marshall, the biggest wilderness in Montana, for seven days.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

That\u2019s amazing. <\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

We\u2019re the only people who would honeymoon with mosquitoes and blisters. But it was so important for us to go and do that, right? We sacrificed what could have been a European vacation or something in order to just reconnect, to have that time with our thoughts. To have to just take care of yourself, I think, is such a powerful thing. But it takes intentionality for sure.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

In the story you write that what often drives people to quit a race of this nature is the loneliness \u2014 it really breaks people. Being a writer is often an exercise in loneliness, also, especially if you\u2019re a freelancer in somewhat remote locations. What\u2019s your relationship to loneliness?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I used to say that I was a raging extrovert, but I\u2019m now married to more of an introvert and I think he\u2019s made me realize I have more introverted tendencies. I mean, as an extrovert, I\u2019m not good with loneliness. And, again, I\u2019ve done nothing like what Susie has undertaken. On the History Channel\u2019s hit show Alone<\/i>, where people are dropped in the wilderness to survive by themselves, the longest anybody has ever gone is 100 days. Susie spent 160 alone. I mean, that\u2019s just incredible.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I think we all have different relationships to loneliness, and it\u2019s finding that line between solitude and loneliness. For me, I know that being around people and relationships feed me so, so much that I can\u2019t be alone for more than 24 hours. And you\u2019re right \u2014 there are different kinds of loneliness, right? There\u2019s this idea that it can be lonely being a freelance writer, because you feel like you\u2019re the only one who\u2019s getting so much rejection with all your pitches, or it seems like everybody else is making it and you\u2019re not.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I started this podcast roughly 10 years ago, to appease a lot of the loneliness I was feeling \u2014 but also to maybe metabolize the toxic feelings of jealousy and competition I was feeling. Because it did feel, like you just said, like everybody else was just killing it. And I was writing about the Daytona 500 for Bleacher Report. I\u2019m like, \u201cThis isn\u2019t the longform journalism that my heroes are doing, my peers are doing.\u201d It took doing the show to realize that maybe I\u2019ve got it all wrong. Maybe I need to try to celebrate other people\u2019s work and have these kinds of nourishing conversations to realize that we\u2019re all wrestling with these feelings. We can look beyond the veneer of social media and get to the ugliness that we\u2019re all dealing with and be like, \u201cOkay, I\u2019m not really alone in this endeavor.\u201d<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

My God, I wish we talked about that so much more. I always think I\u2019m the only one who struggles with it, and I know I\u2019m not, because my husband is also a freelance writer. It\u2019s just this pervasive thing. Maybe there are those writers who don\u2019t struggle with impostor syndrome or rejection, but it seems unlikely. When you\u2019re a creative person, I think you never think that your work is good enough, or that it\u2019s done, or that it\u2019s worthy; we all struggle with that. But we don\u2019t talk about it enough.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

And you\u2019re seeing on Twitter that everyone is getting these great bylines. And you\u2019re like, \u201cDamn, why am I struggling here? I\u2019m spinning my tires in the mud.\u201d But there\u2019s also any number of writing gigs that people aren\u2019t tweeting about that subsidize some of those more prestige pieces \u2014 and no one really talks about the writing we don\u2019t tweet about.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Or the other income! I have a friend who is a great writer, she\u2019s an award winner. She\u2019s told me that she couldn\u2019t write without the income from her Airbnb, right? Or the people who are writing for some weird company on the side to make the narrative reporting work. I\u2019ve had a lot of people tell me that they couldn\u2019t freelance unless their partner was making good money.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I think that way all the time: \u201cWait a second, how have you had three stories in The Atlantic<\/i>?\u201d But there\u2019s such a range of what a writer looks like. It could be the night janitor, whose novel he hasn\u2019t sent out because he\u2019s so terrified. It could be the person who\u2019s only writing notes on the back of a napkin. It could be the full-time New York Times<\/i> journalist. There\u2019s so many different ways to be a writer. I wish that we all talked about that more, so we didn\u2019t feel this pervasive \u201cI haven\u2019t made it\u201d thing.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

How have you made peace with or even embraced rejection?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Oh, God, I have not embraced rejection at all<\/i>. That is so hard. Quite honestly, I\u2019ve decided that I have to be really judicious about what stories I actually want to pitch. And I want to work on bigger projects like this Atavist<\/i> story, because then you don\u2019t have to hustle so much. And you don\u2019t have to face so much rejection when you\u2019re trying to get work. And in some sense for me, that\u2019s really heartbreaking. There was a time when I used to have to write down what I had out, and when to follow up, because I had so many stories I\u2019d pitched. I guess it\u2019s like killing a lot of your darlings before they have the chance to be killed.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I\u2019ve come to see rejection, or even silence, almost as a gift. Maybe this is just my own Jedi mind trick on myself, but if a piece finally is<\/i> accepted, I\u2019m like, \u201cIf it had been accepted five times ago, the pitch wouldn\u2019t be nearly as good or fleshed out. So thanks for those four other rejections because now it\u2019s actually stronger because of it.\u201d<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

That is a far healthier mindset than the one I\u2019ve had, I\u2019m going to start adopting that.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Something struck me about your Atavist<\/i> piece right off the bat. I\u2019m gonna read just the first sentence here, because I think this piggybacks on a lot of things that we were talking about already. \u201cIn the heaving seas of the Southern Ocean, a small red-hauled sailboat tossed and rolled at the mercy of the tail end of a tempest.\u201d It seems like there was a lot of attention put into the wordplay and construction of that sentence. What\u2019s your eye for detail when you\u2019re starting to construct sentences of that nature?<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I actually try to avoid outright alliteration. I love rhythm in sentences \u2014 I actually talked a lot with Jonah about this. As I was writing it, there were a lot more long-ish sentences throughout; in the top edit, Seyward cut a few of them up and made them shorter. I think she was right, but one of the reasons I had chosen some of those longer sentences was to give the piece a dreamlike feel. That\u2019s why that sentence starts out long, right? So that you have this long time to be in this moment.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

You said in working with Jonah and Seyward that you learned a thing or two about pacing.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I told both of them that I wanted this to be a learning experience. I wanted to use this story-editing process with them to learn how to elevate my craft, and they both were very open to that. And they actually have the time to do that and are very willing to do that, which I\u2019ve thanked both of them for. But it\u2019s rare to find editors who have time to do that these days. So that\u2019s a huge, amazing experience if you want to learn as a freelance writer.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I had written Susie\u2019s journey originally, when she set off, in a series of very short vignettes. I had done that because I wanted to convey that not much really happens when you\u2019re sailing, right? And when it does, it happens in bursts. But Jonah had this great point that you can\u2019t really expect your readers to trust you at that point. He said that readers typically take around 750 words \u2014 not all the time, but in general \u2014 to really drop into what the writer wants them to feel and what the writer wants to tell them. So that was huge for me to understand, in terms of pacing and passage construction.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

As we bring this down for a landing, I always like asking writers to offer a recommendation of sorts to the listener.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Well, since we were talking about fiction, I want to recommend to anybody who loves reading joyous writing \u2014 have you ever read any Brian Doyle?<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

Some of his essays.<\/b><\/p>\r\n\r\n\r\n\r\n\r\n\r\n

I just actually read Martin Marten<\/i> twice. The way he spends pages upon pages, creating this whole world before you even know why he\u2019s brought you into it, and you become so close to these characters. It\u2019s just incredible.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n

The other one I\u2019d recommend: my husband and I read out loud to each other, and reading a book out loud is such a different experience. It\u2019s so cool. We just read out loud Tom Robbins\u2019 Skinny Legs and All<\/i>; my God, what a masterpiece.<\/p>\r\n\r\n

<\/p>\n