The old tutorial was built around connectToRedux + Paper + DrawerNavigator
plus a DataList and AbpSelect that no longer ship with the template (PRs
#4635 and #4679 in volosoft/abp-studio cleared and re-themed the React
Native template). The whole document is rewritten so each code block
matches the bookstore-react-native-mongodb sample one-to-one.
Major changes from the previous version:
- Replaces 'add to DrawerNavigator' with 'add to BottomTabNavigator' (the new
default navigation_type).
- Walks through building NativeWind-based DataList and AbpSelect components
before using them in the screens.
- Drops connectToRedux / createAppConfigSelector() in favor of useDispatch +
useSelector(appConfigSelector).
- Keeps Paper TextInput only (the only Paper component the template still
uses); everything else is Pressable + className.
- Backend setup is intentionally short (endpoint + permission summary +
pointer to the Web Application Tutorial) - the focus is the RN side.
- Existing screenshot file paths kept with a TODO marker so they can be
refreshed once the new UI is captured.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand the React UI section to state that ABP 10.4 makes React a first-class modern template option, explain the in-solution React app plus ABP Admin Console approach, list the core tooling (Vite, TypeScript, TanStack Router/Query, Axios, Zod, React Hook Form, Tailwind CSS, shadcn/ui, Vitest), and note creation via the --modern flag or ABP Studio. Rename and expand the ABP Studio AI Agent section to 'ABP Agent', describe its three modes (Agent, Plan, Ask) and capabilities (solution-aware coding, build/run tasks, proxies, migrations, runtime inspection), and highlight workflow integrations (runner, task runner, Git/GitHub, AI commit messages, ABP-aware code review). Add the upgrade-abp-packages.png asset used by the post.
Previously the SkiaSharp resizer ignored ImageResizeArgs.Mode entirely
and always stretched, so callers that never specified a mode were
implicitly relying on stretch output. Map None and Default to Stretch
to preserve that observable behavior while still honoring explicit
Max/Min/Crop/Pad/BoxPad values.
- SkiaSharp resizer now honors ImageResizeArgs.Mode (Stretch, Max, Min,
Crop, Pad, BoxPad) instead of stretching to the target dimensions
regardless of mode. None and Default normalize to Crop to match the
ImageSharp contributor.
- BoxPad now Max-fits the source into the target box first when the
source exceeds it, instead of cropping with negative offsets.
- SkiaSharp compressor caches the bitmap stream length before
SKBitmap.Decode takes ownership of it, so the post-encode size check
no longer accesses a disposed stream and tolerates non-seekable
inputs reaching the contributor directly.
- Add resizer tests for every mode (exact target size for fixed modes,
bounded size for Max/Min, pixel-level transparency check for BoxPad
with a source larger than the target), and a compressor test that
feeds a non-seekable stream directly to the contributor.
Existing tests only checked Result.Length which doesn't depend on
Position, so a contributor that forgot to seek the result stream back
to 0 would still pass. Add an explicit Position == 0 assertion plus a
CopyToAsync round-trip that compares the copied length against the
result stream length, so the same regression cannot slip in again.
Match the ImageSharp and Magick.NET resizer contributors which return
the result stream positioned at the start, so downstream consumers
read the bytes instead of getting an empty read at end-of-stream.
Update the image-manipulation reference to list SkiaSharp alongside
ImageSharp and Magick.NET, and add a SkiaSharp Provider section with
installation steps and the SkiaSharpResizerOptions /
SkiaSharpCompressOptions configuration knobs.
- Add SkiaSharpImageCompressorContributor and SkiaSharpCompressOptions so
Volo.Abp.Imaging.SkiaSharp ships a compressor alongside its existing
resizer.
- Bump Magick.NET-Q16-AnyCPU 14.9.1 -> 14.13.0 to clear the
NU1901/NU1902/NU1903 advisories.
- Mirror _models with Dictionary<TState, ...> populated in AddCheckModels
- GetModelOrNull goes through the dict, matching IsEnabledAsync's first-wins
- Pin first-wins via a regression test
- Add state-aware overload to ISimpleStateCheckerSerializer/Contributor
- Features and Permissions contributors recognise their batch checker and emit a per-state record
- PermissionDefinitionSerializer threads the owning permission through
- Pin equality semantics to match the batch runtime (default comparer)
Add images for React UI and ABP Studio AI Agent and update documentation to include them. Bold and reflow license-related paragraphs in free-licenses-vs-pro-licenses.md to highlight React UI and AI Agent features. Also fix a minor formatting/whitespace issue in generating-crud-page.md (remove extra space around `CSS`). These changes improve clarity and add visual references for the UI and AI Agent features.
When a state has multiple batch checkers (e.g. RequirePermissions plus
RequireFeatures), the per-state result was overwritten on every checker
pass, so a later 'true' silently masked an earlier 'false'. AND-combine
the results to require all checkers to pass.