Remove dead code across utils and designsystem#43
Merged
dadachi merged 1 commit intosubstrate-v2from Apr 30, 2026
Merged
Conversation
- Drop shareImage / toUriCompat / isAlphanumeric from Utility (no production callers; deletes the matching tests) - Drop cardTimeAgoInWordsDateString from DateUtility (unused, was the only consumer of android.text.format.DateUtils) - Delete Tint.kt (TintTheme / LocalTintTheme) — provided by NatTheme but never read anywhere - Drop successContainer / onSuccessContainer from CustomColorScheme and the now-orphaned Teal10 / Teal30 / Teal90 color tokens Net: 7 files touched, 110 lines deleted. No production behavior changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dadachi
added a commit
that referenced
this pull request
May 2, 2026
…#33) * Phase 2A-1: Update ItemTag schema to Rails API v2 (#29) Free-Android port of [nativeapptemplate/NativeAppTemplate-Android#38](nativeapptemplate/NativeAppTemplate-Android#38). Updates the ItemTag schema to match the Rails API v2: - rename queue_number -> name - add description, position - remove scan_state, customer_read_at, already_completed, display_shop_server_path Data layer only — Scan/NFC code is kept and adapted to compile against the new schema. Full Scan/NFC deletion is Phase 2A-2, UI rewrite is 2A-3, further test work is 2A-4. Key changes - item_tag_data.proto: queue_number -> name; reserve 5/7/11; add description and position. - Model (Attributes/Data/ItemTag/Shop/ItemTagData/ItemTagBodyDetail): field renames; added getName/getDescription/getPosition; dropped getScanState/getCustomerReadAt/getAlreadyCompleted/getDisplayShopServerPath. - Meta.maximumQueueNumberLength default 0 -> 256 so the meta field is optional (matches iOS). - ItemTagCreateViewModel / ItemTagEditViewModel: queueNumber -> name; hasInvalidDataQueueNumber -> hasInvalidDataName; updateQueueNumber -> updateName. - Removed production call sites of deleted fields in ShowTagInfoScanResultView, ScanViewModel, ShopDetailCardView, ShopDetailView — each flagged with a // TODO: removed in Phase 2A-2 marker. - Deleted NumberTagsWebpageListView(Model) entirely and removed the navigation wiring / ShopSettings entry. - Updated test fixtures (item_tag.json, item_tags.json) and affected unit tests. ScanViewModelTest deleted ahead of 2A-2. NumberTagsWebpageListViewModelTest removed. Verified locally: ./gradlew assembleDebug, test, spotlessCheck all BUILD SUCCESSFUL. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Phase 2A-2: Remove NFC / QR / Scan (#31) Mirrors NativeAppTemplate-Android PR #39 (which itself mirrors iOS PR #50). After this, the app is a generic CRUD shell with Shops and Settings tabs; ItemTagDetailView is a placeholder (name, description, state, completedAt). ### Deletions - NfcError; ItemTagWriteView/VM + test - ui/scan/* (ScanView, ScanViewModel, DoScanView, DoScanViewModel, CompleteScanResultView, ShowTagInfoScanResultView, ScanNavigation) + DoScanViewModelTest - Models: CompleteScanResult, CompleteScanResultType, ShowTagInfoScanResult, ShowTagInfoScanResultType, ItemTagInfoFromNdefMessage, ItemTagType, ScanState, ItemTagData - Proto schemas: scan_result.proto, item_tag_data.proto, item_tag_info_from_ndef_message.proto - res/raw/nfc_reader.json ### Strip / rewrite - MainActivity: dropped NFC imports, onNewIntent, ACTION_NDEF_DISCOVERED handling, singleTask launch mode - MainActivityViewModel: rewritten minimal (logout + permissions refresh + didShowTapShopBelowTip) - NatAppState / NatNavHost / TopLevelDestination: dropped SCAN_TAB, shouldNavigateToScanView flow, navigateToScan helper, scan nav graph - ShopDetailView / VM: dropped queue instructions block, ReadInstructionsTip, didShowReadInstructionsTip; renamed resetItemTag -> idleItemTag and swipe action "Reset" -> "Idle" (width 64dp -> 96dp) - ShopSettingsView / VM: removed the "Reset Number Tags" section, resetShop flow - ItemTagDetailView / VM: placeholder (name, description, state, completedAt) - LoginRepository (+ Impl) / NatPreferencesDataSource: dropped scan-related setters/getters, didShowReadInstructionsTip - ShopRepository / ShopApi / Impl: dropped resetShop - ItemTagApi / Repository / Impl: renamed resetItemTag (/reset) -> idleItemTag (/idle) - Utility: dropped scanUri(), extractItemTagInfoFrom(), NFC imports - NatConstants: dropped SCAN_PATH, SCAN_PATH_CUSTOMER - UserData: dropped didShowReadInstructionsTip, scanViewSelectedTabIndex, shouldFetchItemTagForShowTagInfoScan, shouldCompleteItemTagForCompleteScan - shopSettingsNavigation: dropped ItemTagWriteRoute / itemTagWriteView - Demo / test repos updated to match trimmed interfaces; obsolete tests removed (UtilityTest scanUri, CodedErrorTest NfcError, ItemTagDetailVMTest isLock, ShopDetailVMTest reset/didShowReadInstructionsTip) ### Config - AndroidManifest.xml: removed NFC permission, android.hardware.nfc feature, NDEF_DISCOVERED intent-filter, singleTask launch mode - build.gradle.kts / libs.versions.toml: removed compose-qr-code, capturable, lottie-compose - user_preferences.proto: removed scan fields - strings.xml: removed ~25 scan/NFC/QR strings; onboarding descriptions 1-13 rewritten to generic "Welcome to the app." placeholder so OnboardingView still compiles (worth redesigning or deleting in a follow-up) ### Test plan - [x] ./gradlew assembleDebug passes - [x] ./gradlew test passes - [x] ./gradlew spotlessCheck passes - [x] ./gradlew lint passes - [x] ./gradlew buildHealth passes - [ ] Manual smoke test on device/emulator: 2 tabs visible (Shops / Settings), no Scan tab; sign-in works; ItemTag create / view detail placeholder / edit / delete flows work Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Phase 2A-3: Generic CRUD UI for ItemTag (#32) Mirrors NativeAppTemplate-Android PR #40 (which mirrors iOS PR #50). After this sub-phase, ItemTag is a generic parent-child CRUD UI: Create/Edit accept any unicode/symbol name with multi-line description, Detail screen shows a state badge + completed timestamp + Mark-as-completed/idled toggle, the list card surfaces description preview + state. Differences from the paid PR: this Free repo has no per-action permission system (canCreateShops / canUpdateShops / canDeleteShops / canManageTags), so all permission-gating in views and ViewModels is omitted — the FAB, swipe-delete, edit toolbar, and state-toggle button are always shown. ### Data layer - ItemTag.position: Int? -> Int = 0. Rails server's set_position_if_missing always populates this; client trusts the contract. - ItemTagBodyDetail: dropped position (server auto-assigns). - Data.getPosition() / ItemTag.getPosition(): now non-null Int. ### Rename maximumQueueNumberLength -> maximumNameLength - Meta serial name maximum_queue_number_length -> maximum_name_length; default fallback 256 -> 100. - Threaded through Permissions, UserData, user_preferences.proto, NatPreferencesDataSource, LoginRepository(+Impl), TestLoginRepository, DemoLoginRepository. ### ItemTag Create + Edit - Validation relaxed: drop alphanumeric and count >= 2 checks. Valid name is 1 - maximumNameLength chars (any unicode/symbols/spaces). - New description field: 0 - 1000 chars, optional, multi-line OutlinedTextField (minLines = 4). NatConstants.MAXIMUM_ITEM_TAG_DESCRIPTION_LENGTH = 1_000. - Standard keyboard (no .Ascii). - hasInvalidData checks both name AND description; Edit's also requires that name OR description changed. ### ItemTag Detail full rewrite - HeaderRow: name + IdlingTag() / CompletedTag() badge. - DescriptionSection: hidden when blank. - CompletedAtRow: shown only when state == Completed. - StateToggleButton: flips between Mark as completed and Mark as idled; uses MainButtonView; disabled while isToggling. - ViewModel: new isToggling, completeItemTag(), idleItemTag(). Errors set uiState.message; success silently updates itemTag (matches the no-success-toast pattern from #31). ### ItemTag list card - Headline: name + state badge. - Supporting: description preview (2 lines, ellipsis) + completed timestamp when state == Completed. ### Date helpers - Add ZonedDateTime.cardDateTimeString() and String.cardDateTimeString() to DateUtility. - Card date format MMM dd yyyy -> yyyy/MM/dd. - ShopDetailCardView and ItemTagListCardView use cardDateTimeString(). ### Strings + constants - New: name_label, description_label, completed_at_label, item_tag_name_placeholder, item_tag_name_is_invalid, item_tag_description_is_invalid, item_tag_name_help (format), item_tag_description_help (format), mark_as_completed, mark_as_idled. - Removed queue-specific: tag_number, tag_number_is_invalid, zero_padding. ### Tests - ItemTagCreateViewModelTest: new validation matrix (unicode/symbols, 100/101 boundary, 1000/1001 description boundary). - ItemTagEditViewModelTest: rewritten - unchanged-form invalid, description-only change valid, blank name invalid, unicode/symbols valid. - ItemTagDetailViewModelTest: + completeItemTag / idleItemTag success cases. - DateUtilityTest: + cardDateTimeString tests. ### Test plan - [x] ./gradlew clean assembleDebug passes - [x] ./gradlew test passes - [x] ./gradlew spotlessCheck passes - [x] ./gradlew lint passes - [x] ./gradlew buildHealth passes - [ ] Manual smoke test on emulator: sign in, create tag with "Buy milk 🥛" and multi-line description; mark complete; mark idled; edit description; delete Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Comment out Unit Tests step in CI The test takes a long time to run, so I've commented it out. spotlessCheck and Android Lint remain active. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Reveal swipe actions from trailing (right) edge (#34) Flip SwipeableItemWithActions so users drag the row right-to-left to reveal action buttons, with the buttons sitting on the trailing (right) edge instead of the leading (left) edge. Matches the iOS app's swipeActions(edge: .trailing) and the platform-conventional swipe-to-reveal gesture. - Actions Row aligned to Alignment.CenterEnd of the wrapping Box - Drag offset coerced to [-contextMenuWidth, 0f] - Revealed anchor flipped to -contextMenuWidth; half-way fling threshold checks <= -contextMenuWidth / 2f Public API (isRevealed, actions, onExpanded, onCollapsed, content, modifier) is unchanged, so both call sites pick up the new direction with no edits: - ShopDetailView — Complete / Idle actions on item-tag rows - ItemTagListView — Delete action on item-tag rows Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop maximum_name_length; remove How-To-Use from Settings (#35) Two unrelated substrate-v2 cleanups bundled here. ## 1. Drop maximum_name_length from permissions; move to NatConstants The server no longer sends maximum_name_length in /shopkeeper/permissions; the client already tolerated its absence via a default. Promote the value to a constant and drop the dead plumbing. ### Stop reading maximum_name_length from /shopkeeper/permissions - Meta: drop the @SerialName("maximum_name_length") field. - Permissions: drop getMaximumNameLength() helper. - UserData: drop maximumNameLength field. - user_preferences.proto: reserved 23 (was maximum_name_length) so the wire number isn't reused. - NatPreferencesDataSource: drop the read in the userData mapping, the write in setPermissions, and the getMaximumNameLength() flow. - LoginRepository (interface + impl + DemoLoginRepository + TestLoginRepository): drop getMaximumNameLength(). ### Move maximumNameLength to NatConstants - NatConstants: add MAXIMUM_ITEM_TAG_NAME_LENGTH = 100. - ItemTagCreateViewModel + ItemTagEditViewModel: - UiState.maximumNameLength default now reads the constant. - Drop the loginRepository constructor param — it was only used for getMaximumNameLength(). - ItemTagCreateViewModel.reload() simplifies to a state reset. - ItemTagEditViewModel.fetchData() drops the combine() pairing the item-tag flow with the maximum-name-length flow. - Tests rewritten to drop the now-removed loginRepository wiring and the dead .copy(maximumNameLength = 100) calls; new maximumNameLength_matchesConstant tests assert against the NatConstants value (100). ## 2. Remove "How To Use" entry from Settings Drop the SettingsView list item linking to myturntag.com/how — a queue-product help page that no longer matches the substrate-v2 generic CRUD app surface. The string resource (R.string.how_to_use), the NatConstants.HOW_TO_USE_URL constant, and the OnboardingView call site are left in place because they are still wired and may be repurposed. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add client-side length caps + truncation for Shop name/description (#36) Mirror the ItemTag pattern (PR #35) for Shop. Server has no caps on Shop name/description; this is a client-only UX guard. ### Changes - NatConstants: MAXIMUM_SHOP_NAME_LENGTH = 100, MAXIMUM_SHOP_DESCRIPTION_LENGTH = 1_000. - strings.xml: new shop_name_is_invalid, shop_description_is_invalid, shop_name_help, shop_description_help (parametric). - ShopCreateViewModel + ShopBasicSettingsViewModel: - UiState gains maximumNameLength / maximumDescriptionLength (defaulted to the constants). - hasInvalidData() splits into hasInvalidDataName() + hasInvalidDataDescription(); the parent now ORs both. - updateName() / updateDescription() reject input over the cap (mirrors the existing ItemTagCreateViewModel / ItemTagEditViewModel Android pattern). - ShopCreateView + ShopBasicSettingsView: switch supportingText to the two-line layout (always-visible help + conditional red "is invalid" line), matching ItemTagCreateView / ItemTagEditView. Description switches to heightIn(min=120) + minLines=4. - Tests: maximumNameLength_matchesConstant / maximumDescriptionLength_matchesConstant, boundary tests at 100 / 101 / 1000 / 1001 chars on both ShopCreateViewModelTest and ShopBasicSettingsViewModelTest. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ShopDetailCardView: 2-column layout with description (#37) * ShopDetailCardView: 2-column layout with description Mirror iOS ItemTagListCardView's 2-column HStack pattern in ShopDetailCardView so each item-tag row in ShopDetailView surfaces the description alongside the name. Layout: - Left column (weight 1): name (titleLarge), description (bodySmall, max 2 lines, ellipsis) hidden when blank. - Right column (minWidth 82dp, end-aligned): state tag — CompletedTag + completedAt for Completed; IdlingTag for Idled. Matches iOS ItemTagListCardView's HStack { VStack(alignment: .leading) [name, description] | Spacer | VStack(alignment: .trailing) [tag, completedAt] } shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Move description from ShopDetailCardView to ItemTagListCardView Drop description block from ShopDetailCardView and revert to the flatter row layout. Restructure ItemTagListCardView from ListItem to a manual Row with a 2-column layout that surfaces the description. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop unused tags-scanned count and howToUse; tighten ItemTag labels (#38) Port iOS NativeAppTemplate-iOS#61 to Android: - Drop `scannedItemTagsCount` from Attributes/Data and remove the "tags scanned by customers" stat from ShopListCardView. - Add a left-aligned shop_detail_instruction header to ShopDetailView ("Swipe an item tag to change its status."). - Swap OnboardingView's How-To-Use link for the Support Website link and trim onboarding from 13 to 8 descriptions; update placeholder strings to match the iOS copy. - Normalize ItemTag labels: label_add_tag/add_tag_description/ label_edit_item_tag/title_delete_item_tag and message_item_tag_* values now read "Item Tag" / "Item tag" consistently. - Drop unused HOW_TO_USE_URL, R.string.how_to_use, R.string.learn_more. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Slim onboarding to 4 slides and add ImageOrientation enum (#39) Mirrors NativeAppTemplate-iOS#63 / NativeAppTemplate-Android#52: drops slides 5-8, replaces descriptions with neutral placeholders, and introduces an ImageOrientation enum so slides drive their own bottom-padding instead of a Bool. View now reads the slide list from the ViewModel rather than a hard-coded count. Also swaps SignUpOrSignInView from ic_overview1_slim to a dedicated ic_hero image and prunes unused overview drawables. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add tests for Onboarding model, MainActivityViewModel, AuthInterceptor (#40) Mirrors NativeAppTemplate-Android#53. Covers three previously-untested areas: - Onboarding data class + ImageOrientation enum (defaults, equality, enum entries). - MainActivityViewModel uiState mapping (Loading, Success, isLoggedIn reflection) and the didShowTapShopBelowTip toggle persisting through the repository. - AuthInterceptor header injection (with/without auth, base headers, URL preservation), using an in-test RecordingChain so the test runs as a plain JVM unit test. TestLoginRepository.setDidShowTapShopBelowTip now mirrors the other setters and updates the user-data flow so the persistence test can observe it. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Ignore .claude/scheduled_tasks.lock Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop NFC-removal leftovers and tighten a few obvious patterns (#41) - Delete CustomerScannedTag composable (dead since NFC/scan removal). - Remove stale TODO marker in ShopDetailCardView left over from the schema-v2 drop of scanState/customerReadAt. - Collapse NatConstants.baseUrlString into an expression-bodied function. - Drop the redundant intermediate Flow vals (and now-unused imports) inside MainActivityViewModel.updatePermissions. Mirrors NativeAppTemplate-Android#54. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix dead password tests and add ItemTag whitespace-name regression tests (#42) Two bugs in test assertions found while auditing validators: 1. Three password tests in SignInEmailAndPasswordViewModelTest and SignUpViewModelTest called hasInvalidDataEmail() instead of hasInvalidDataPassword(). Email is blank by default in those setups, so assertions passed for the wrong reason and the password rules were never actually exercised. Pointed them at hasInvalidDataPassword(). 2. Added whitespaceOnlyName_isInvalid regression tests for both ItemTagCreateViewModel and ItemTagEditViewModel to lock in the isBlank() name validation already in place. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Remove dead code across utils and designsystem (#43) - Drop shareImage / toUriCompat / isAlphanumeric from Utility (no production callers; deletes the matching tests) - Drop cardTimeAgoInWordsDateString from DateUtility (unused, was the only consumer of android.text.format.DateUtils) - Delete Tint.kt (TintTheme / LocalTintTheme) — provided by NatTheme but never read anywhere - Drop successContainer / onSuccessContainer from CustomColorScheme and the now-orphaned Teal10 / Teal30 / Teal90 color tokens Net: 7 files touched, 110 lines deleted. No production behavior changes. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Clean up legacy Number Tag/NFC artifacts and tighten utilities (#44) - Remove leftover terminology and dead code from the previous "Number Tag" / NFC / QR-image feature set: README copy, NATA-3xxx error code row in CLAUDE.md, and the unused FileProvider declaration plus its filepaths.xml resource. - Tighten validation messaging and small utilities: clarify item tag validation error messages, drop unused card date/time string overloads (production only uses String.cardDateTimeString), and rename validateEmail -> isValidEmail to match the is* boolean-predicate convention. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Ignore docs-private/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Move phase2 prestep number-tag-rename doc out of repo Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Normalize substrate naming to single NativeAppTemplate stem (#45) Rename all `Nat`-prefixed Kotlin symbols to `NativeAppTemplate*` (NatApp, NatAppState, NatConstants, NatPreferencesDataSource, NatNavHost, NatAlertDialog, NatBackground, NatBottomBar, NatDispatchers, NatNavigationBar*, NatOkHttpClient, NatPreferences, NatTheme, NatTypography, plus rememberNatAppState) and rename the 8 corresponding source files. Rename Compose theme styles `Theme.Nat` and `Theme.Nat.Splash` (and the `NightAdjusted.Theme.Nat` parent) to the `Theme.NativeAppTemplate.*` family in themes.xml, values-night/themes.xml, and AndroidManifest.xml. Rename the three Gradle properties `NATEMPLATE_API_{DOMAIN,PORT,SCHEME}` to `NATIVEAPPTEMPLATE_API_*` in app/build.gradle.kts, README.md, and CLAUDE.md. Rename the `NATA-XXXX` error-code prefix to `NATIVEAPPTEMPLATE-XXXX` across ApiException.kt, AppError.kt, CodedErrorTest.kt, CLAUDE.md, and CHANGELOG.md. Goal: every reference to the product uses one canonical stem (`NativeAppTemplate`) so the upstream substrate renamer's `NativeAppTemplate -> <slug-pascal>` rename pair handles every occurrence in one rule. After this PR, `rg "Nat[A-Z]|NATEMPLATE|NATA-"` returns zero matches outside `.git/` and `docs-private/`. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add Unreleased changelog entry for substrate naming normalization Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Expand 3.2.0 changelog with full upstream entry Mirror the 3.2.0 changelog content from upstream PR #41 and add the substrate naming normalization line under Changed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
shareImage/toUriCompat/isAlphanumericfromUtility(no production callers; deletes the matching tests)cardTimeAgoInWordsDateStringfromDateUtility(unused, was the only consumer ofandroid.text.format.DateUtils)Tint.kt(TintTheme/LocalTintTheme) — provided byNatThemebut never read anywheresuccessContainer/onSuccessContainerfromCustomColorSchemeand the now-orphanedTeal10/Teal30/Teal90color tokensNet: 7 files touched, 110 lines deleted. No production behavior changes.
(Ports nativeapptemplate/NativeAppTemplate-Android#56.)
Test plan
./gradlew spotlessApply./gradlew test./gradlew assembleDebug🤖 Generated with Claude Code