diff --git a/CHANGELOG.md b/CHANGELOG.md index e2c994a..b818048 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - Move agent instructions from `CLAUDE.md` to `AGENTS.md` so Claude Code, Codex, and other agents share one file. `CLAUDE.md` now only imports it (`@AGENTS.md`) ### Fixed +- Comments say "the agent" instead of the agent's name (renamed with the product) and drop "a"/"an" before domain words, which can't follow the first sound of the renamed word; test fixtures say "This is shop.". `StringResourcesTranslationTest` now fails on "a" or "an" before a domain word or the product name in an English string - Error messages are in the app language and say what the user can do, with the same wording as NativeAppTemplate-Free-iOS; the error codes are unchanged. A request that got no answer (no network, a timeout) or an error status without a message (e.g. a 502 page) shows `[NATIVEAPPTEMPLATE-2002]` "Something went wrong while communicating with the server. Please try again later." (サーバーとの通信中に問題が発生しました。しばらくしてからもう一度お試しください。) instead of the English system text (e.g. "Processing error: Unable to resolve host ..." or "Processing error: HTTP 502"). A response the app could not process (`2002`) and `1001` show "An unexpected error occurred." (予期しないエラーが発生しました。). The server's own messages are shown as is, without the developer suffix " [Status: 422]" (`2001`) or the "Processing error: " prefix (sign-in's "Invalid login credentials"). The details are logged with the code instead (`adb logcat -s ApiError`) - An error snackbar no longer stays after the screen recovers (e.g. the offline `[NATIVEAPPTEMPLATE-2002]` error still showing after the network is back and Reload succeeded). Every screen's load (Reload, pull to refresh, resume) and every sign-in attempt now clears the previous attempt's error when it starts, which closes its snackbar; an error of the new attempt still shows. Ported from MyTurnTagCreator-Android #139 - The "Shop deleted" notice no longer stays over the sign-in screen after signing out. The notices stored before the app restarts itself are about the session, so signing out closes the one still on screen (`showNoticeStoredForLaunch`); the notices that explain a sign-out (email changed, account deleted) are unchanged. Ported from MyTurnTagCreator-Android #143 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a96fa88..fa34128 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -3,7 +3,7 @@ Japanese. Keep every translatable key of values/strings.xml here (StringResourcesTranslationTest fails otherwise), and use the terms of the template API's config/locales/ja.yml: Shop = 店舗, Item Tag = アイテムタグ, idled / completed = 未完了 / 完了. - nativeapptemplate-agent renames 店舗 and アイテムタグ as plain substrings, so always write them in + The agent renames 店舗 and アイテムタグ as plain substrings, so always write them in full: never ショップ / 店 / お店, and never shorten アイテムタグ to タグ or アイテム. --> diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/i18n/StringResourcesTranslationTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/i18n/StringResourcesTranslationTest.kt index 23c08a0..2f58f5f 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/i18n/StringResourcesTranslationTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/i18n/StringResourcesTranslationTest.kt @@ -44,6 +44,17 @@ class StringResourcesTranslationTest { assertTrue("Format arguments differ:\n" + mismatches.joinToString("\n"), mismatches.isEmpty()) } + // The agent renames the domain words and the product name, so an article in front of one can't + // follow the new word's first sound. + @Test + fun english_hasNoArticleBeforeRenamedWords() { + val article = Regex("""\ban? (item tags?|shops?|shopkeepers?|NativeAppTemplate)\b""", RegexOption.IGNORE_CASE) + val texts = english.mapValues { it.value.text } + + englishPlurals.flatMap { (name, items) -> items.map { (quantity, text) -> "$name/$quantity" to text } } + val wrong = texts.filterValues { article.containsMatchIn(it) }.keys + assertTrue("Drop the article before the renamed word in: $wrong", wrong.isEmpty()) + } + @Test fun plurals_matchBetweenEnglishAndJapanese() { assertEquals(englishPlurals.keys, japanesePlurals.keys) @@ -75,7 +86,7 @@ class StringResourcesTranslationTest { @Test fun japanese_shopIs店舗() { - // nativeapptemplate-agent renames 店舗 as a plain substring, so a shop must never be ショップ, + // The agent renames 店舗 as a plain substring, so shop must never be ショップ, // 店 or お店, or a generated app would keep this template's word. val katakana = japanese.filterValues { "ショップ" in it.text }.keys assertTrue("Use 店舗: $katakana", katakana.isEmpty()) @@ -85,7 +96,7 @@ class StringResourcesTranslationTest { @Test fun japanese_neverShortensアイテムタグ() { - // nativeapptemplate-agent renames アイテムタグ as a plain substring, so an item tag must always be + // The agent renames アイテムタグ as a plain substring, so item tag must always be // written in full; a bare タグ or アイテム would survive the rename. val shortened = japanese.filterValues { resource -> val rest = resource.text.replace("アイテムタグ", "") diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailViewModelTest.kt index d38837c..c48947d 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailViewModelTest.kt @@ -186,7 +186,7 @@ class ShopDetailViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private var testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopBasicSettingsViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopBasicSettingsViewModelTest.kt index 506e113..54a484b 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopBasicSettingsViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopBasicSettingsViewModelTest.kt @@ -262,7 +262,7 @@ class ShopBasicSettingsViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private val testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopSettingsViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopSettingsViewModelTest.kt index 8a835fa..92582b8 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopSettingsViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/ShopSettingsViewModelTest.kt @@ -143,7 +143,7 @@ class ShopSettingsViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private val testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagCreateViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagCreateViewModelTest.kt index 69776e6..c948347 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagCreateViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagCreateViewModelTest.kt @@ -168,7 +168,7 @@ class ItemTagCreateViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private var testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListViewModelTest.kt index 1dfe26a..2775448 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListViewModelTest.kt @@ -396,7 +396,7 @@ class ItemTagListViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private var testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopCreateViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopCreateViewModelTest.kt index e6b4b0b..1e92ff1 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopCreateViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopCreateViewModelTest.kt @@ -155,7 +155,7 @@ class ShopCreateViewModelTest { private const val SHOP_TYPE = "shop" private const val SHOP_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1A" private const val SHOP_NAME = "8th & Townsend" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private val testInputShopsData = diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopListViewModelTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopListViewModelTest.kt index 2776acc..8ae57d8 100644 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopListViewModelTest.kt +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shops/ShopListViewModelTest.kt @@ -137,7 +137,7 @@ private const val SHOP_3_ID = "5712F2DF-DFC7-A3AA-66BC-191203654A1C" private const val SHOP_1_NAME = "8th & Townsend" private const val SHOP_2_NAME = "Kansas & 16th St" private const val SHOP_3_NAME = "Safeway San Francisco 1490" -private const val SHOP_DESCRIPTION = "This is a shop." +private const val SHOP_DESCRIPTION = "This is shop." private const val SHOP_TIME_ZONE = "Pacific Time (US & Canada)" private val testInputShopsData = listOf( diff --git a/model/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ModelJsonTest.kt b/model/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ModelJsonTest.kt index 31eb716..0215824 100644 --- a/model/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ModelJsonTest.kt +++ b/model/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ModelJsonTest.kt @@ -43,7 +43,7 @@ class ModelJsonTest { assertEquals(7, shop.getCompletedItemTagsCount()) } - // A shop without the optional attributes falls back to the defaults (iOS ShopAdapter: "" and 0). + // Shop without the optional attributes falls back to the defaults (iOS ShopAdapter: "" and 0). @Test fun shop_withoutOptionalAttributes_usesTheDefaults() { val shop = json.decodeFromString("""{"data": {"id": "shop-1", "type": "shop", "attributes": {"name": "Fox Plaza"}}}""")