# Highlights

- Upgraded internal NodeJS version from v16 to v18.
- app.AddModule now uses the real npm rather than live-plugin-manager.
- Fixed tons of bugs and issues (thanks to AlanH for reporting most of them).

# NOTE: Breaking changes in Hybrid controls

1. Unitless setMargins values were silently invalid CSS in 2.80 but are now 
   interpreted as fractions of the parent in 2.81, so setMargins(10, 10) becomes 1000%.

2. BottomNavbar changes breaks older apps: addBottomNavbar(parent, navs) now defaults 
   to filling the parent’s full height with an empty layout above the bar (like upside down tabs), 
   whereas 2.80 fixed it to the screen bottom — old apps only works correctly now if the 
   new 'BarOnly' option is used.



# Release History

## DS 2.81.0
- DroidScript is now 64-bit only (arm64-v8a); 32-bit devices should stay on 2.80.
- Updated the Node plugin to Node 18 (16 KB page aligned, 64-bit only).
- Fixed node module installs (eg. ide.AddModule) hanging; they now use npm.
- Fixed Premium sometimes not being recognised by plugins (eg. 'Node not licensed').
- Fixed GameView samples showing 'error OnLoad not defined'.
- Fixed app.Animate() ignoring the fps value (use 'legacy' option for old behaviour).
- Fixed "Orientation" sensor azimuth always 0 on phones without the legacy orientation sensor.
- app.Path2Uri() now returns a SAF uri for paths in folders granted with app.GetPermission().
- Fixed app.Path2Uri() returning empty for files in app.GetPrivateFolder() folders.
- Fixed file functions (eg. app.ListFolder) failing on a folder granted with app.GetPermission() itself.
- Fixed crash in WebViews when downloading a data: url (eg. <a download> with canvas.toDataURL()).
- app.SetAppLanguage accepts a language code or name, and works without lang.json (#15).
- app.WalkFolder 'Project' option walks only the app folders (#29).
- app.SetWifiEnabled shows the Wi-Fi panel on Android 10+, which ignores setWifiEnabled (#35).
- app.SetBluetoothEnabled asks the user on Android 13+, which ignores enable/disable (#63).
- Fixed List button/gradient styles not showing their backgrounds (#40).
- SetBackGradient accepts an empty third colour (#39).
- Toggle 'NoPad' trims padding to just clear the indicator; 'Custom' copes with themes without a button style (#43).
- app.AddTabs/CreateTabs work without options (#45).
- Tabs.GetLayout gives a clear error for an unknown tab name (#77).
- app.GetLastToggle returns a touched toggle that has no OnTouch handler (#51).
- app.DiscoverBtDevices always calls OnComplete, even when discovery can't start (#59).
- app.ShowTextDialog no longer needs a callback; its and CheckList's buttons use app.Translate text (#62).
- APK builder prompt now says 'Install now?', as it doesn't run the app (#93).
- app.IsDebugVisible returns false before the debug overlay exists (#95).
- SetBackAlpha and Image.SetAlpha accept 0-1 or 0-255 (#96).
- Plugins page no longer logs a ReadFile warning for Registry plugins (#98).
- app.CreateFile works on content: uris, and app.ReadFile on FileProvider/MediaStore uris (#157).
- Updated the Hybrid UI plugin (enjine-ui) from 0.31 to 0.33.3, fixing:
- border, borderColor and borderStyle getters work on every control (#46).
- Dropdown keeps its selection in step when items are removed or renamed (#55).
- Button 'Upload' opens the file picker without an onTouch handler (#56).
- CheckboxGroup/SwitchGroup addItem ticks the right row; SwitchGroup keeps item order (#64).
- options property for ActionSheet, BottomSheet, Dialog, Popup and ProgressDialog (#65).
- A disabled control never calls its onTouch (#67).
- Primary/Secondary for List and Accordion icons; Accordion backColor fills its panels (#68).
- BottomNavbar color property; activeColor reports the option's colour (#69).
- Button and Text 'KeepCase' option (#70); Text verticalAlignment getter (#71).
- BottomNavbar hideLabels, active colour and disabled look (#73, #75).
- Button 'Icon,Large' shows a large icon (#78).
- WebView reload(), stop() and print() work (#88).
- SwitchGroup edge and checked state; RadioGroup icons (#91, #92).
- ColorPicker/getPixelColor docs: #aarrggbb puts alpha first, unlike CSS (#96).
- Card textColor/textSize style its text, and Card can be disabled; numeric textSize is in px (#99).
- Drawer 'Permanent' and 'Persistent' options; open/close callbacks fire once per change (#106).
- Breadcrumbs docs (#108).
- ActionSheet list setter, getter without Cancel, plain onSelect text (#109).
- Tabs 'Standard' variant honoured, unknown names guarded (#110).
- List textPrimary/textSecondary on icon actions (#111).
- Chip image avatars (#112).
- AppBar disabled state (#114).
- TextField maxRows auto sizing, multiline Enter, colour style setters (#115).
- Dropdown and Table accept an empty list; Table keeps the caller's list (#116, #117).
- Missing and restricted routes show the app's 404/403 layouts (#118).
- itemPadding accepts a number, array, "l,t,r,b" or object on Accordion, RadioGroup, CheckboxGroup, List and Menu (#119, #140).
- Divider 'Inset' option; Checkbox 'Small' option (#121, #122).
- Accordion setTitleTextByIndex, getLayoutIndex(title), expand icon weight, Absolute layouts (#123, #139, #141, #142).
- removeItemByIndex ignores unknown names/indexes; Timeline removal without Custom no longer throws (#126).
- Select 'Disabled' with 'AutoFocus' no longer loops (#127).
- Switch edge setter takes effect (#128).
- Slider 'False' track and boolean valueLabelDisplay (#129).
- Select 'Radio' choices can be cleared by tapping again; 'Required' keeps one chosen (#130).
- Button, ButtonGroup and SpeedDial 'Default' option gives the default colour (#131).
- backColor for ActionSheet, BottomSheet, Popover, Popup, Dialog and the pickers (#132).
- HTMLElement textColor/textSize/disabled/options no longer throw (#134).
- SwitchGroup 'Left' option puts the switches first (#135).
- 'Edge' option lines Checkbox, CheckboxGroup and RadioGroup up with the layout edge (#136).
- Card setHeaderItems/setBodyItems (add* kept as aliases) (#137).
- 'Html' option for Dialog, Popup, Alert, Card, List and Timeline (#138).
- getItem, getItemByIndex and getItemIndex on the list-based controls (#143).
- Dialog titleColor works (#144).
- TreeView options setter no longer throws; MultiSelect implemented; disabled works (#145, #153).
- Fixed-size controls' width/height are relative to the screen (#146).
- List and SwitchGroup list getter returns the documented order (#147, #148).
- RadioGroup value current in onTouch; css colours in setColor; setTextSizeByIndex (#149, #151).
- SpeedDial copies its actions list, guards unknown names, toolTipPosition alias (#152).
- Popup no longer closes on the tap that showed it from an onTouch (#154).
- ButtonGroup activeItems sets several items; only 'Radio' is limited to one (#155).
- Menu Primary/Secondary/Error colour the item text, not just the icons (#156).

## DS 2.80.0

- Fixed SAF file write truncation bug.
- Fixed `app.CreateShortcut` bug in APKs.
- Added new `app.GetSafeArea()` method with `cutout` and `system` option.
- Fixed `app.EnableBackKey(false)` in Android 16 APKs.
- Fixed Google Play warning about 16 KB memory page sizes.
- Improved SAF support in all file handling functions.
- `app.ListPermissions( "all/internal/external/usb" )` now returns use-able URIs.

## DS 2.79.2b

- Updated ApkBuilder to target API 36.
- Updated ApkBuilder to use Billing v8.

## DS 2.79.1b

- Fixed missing ScratchPad extension on device IDE.
- Fixed module/ESM based projects not working in APKs (new apkbuilder needed).
- Fixed issue with `app.SetScreenMode( "game" )` showing black bar at bottom.
- Filtered `.*android_webview/browser.*` errors in NodeJS apps.
- Added 'AllFiles' permission to `app.GetPermissions`/`CheckPermissions` (for X version).
- Fixed import statements not working for libs in sub-folders.
- Fixed issue with wifi-ide not showing app-icon.png files.

## DS 2.78.9

- Fixed app icon and provider authority issue in APK/AAB builder.
- Set AAB builder default to SDK level 35.

## DS 2.78.8b

- Added `app.GetNavBarHeight` method.
- Updated nav bar detection/measuring to support runtime changes.

## DS 2.78.7b

- Enabled drawing over camera notch.
- Changed internal method for calculating Navbar height.

## DS 2.78b1

- Updated `targetSdkVersion` to SDK 35.
- Updated Google Play Billing Library to version 7.0.0.
- Added support for edge-to-edge mode on Android 15+.
- Permission "Media" is now only added in 'X' version (due to GPlay restriction).
- Fixed bug preventing spks/ppks/epks from being installed from file managers.
- Fix docs open/close, unwanted refresh bug.
- Added `wbs.SetOnWsReceive`, `wbs.SetOnWsOpen`, `wbs.SetOnWsClose` callbacks.
- App name is now (space) trimmed when creating a new app on the device.
- App now starts up faster (no orientation flips).
- Added new `cfg.EdgeToEdge` mode to enable it if available on the device.
- Added new `app.IsEdgeToEdge()` method.

## DS 2.77b2

- Fixed bug where HTTP PUT requests were failing in Hybrid and Python apps.
- Added ForceCors option to `app.SetOptions` to force CORS checks on Hybrid and Python apps.
- Added new obfuscator and made `ide.Obfuscate` modal.
- Added support for Espressif ESP32 chips to UsbSerial module (tested on QT-Pi-ESP32-S3).
- Added mobile programming support for ESP32 chips running MicroPython + examples.
- Fixed editor not resizing after returning from docs when keyboard was show.
- Fixed IDE 'Create Shortcut' error always showing on Android 26+.
- Fixed APKBuilder mistakenly using old DS engine (caused mimetype errors etc).
- Stopped using V8 libs for IDE (js engine too old for new obfuscator libs).
- Downloading APKBuilder from plugins menu now downloads matching build version.
- Fixed Notificationlistener or `_AddOptions("NotifyService")` making project behave like HTML project.
- Fixed `app.QueryContent()` always asking for "Media" permissions (use `_AddPermissions` instead).
- Marked 'Query Videos/Images' samples as 'X' version only (due to new Google Play restrictions).
- Fixed HTML and Hybrid apps now auto-size when keyboard is shown.

## DS 2.77b1

- Removed READ_MEDIA_IMAGES/VIDEOS permissions for GPlay version (Google requirement).
- Removed FOREGROUND_SERVICE_LOCATION permission for GPlay version (Google requirement).
- Re-enabled 32bit ARM support (too many devices still running 32bit).

## DS 2.76b3

- Fixed bug when switching between 'Game' mode and 'Normal' mode.
- Updated docs to include Python fixes.
- Updated UI controls to v0.31.
- Fixed delay when first showing left side panel (docs).
- Wifi-IDE: New UI for text search (similar to Edit extension).
- Wifi-IDE: When creating and naming new files, the enter key now confirms the dialog.
- Wifi-IDE: Fixed meta key not working for MacBooks.
- Fixed Pixel7 text sizing and offscreen button issues.
- Fixed `app.IsTablet` response for Pixel7 (and other large phones).

## DS 2.76b2

- 'Game' mode now fills the camera notch area too (if present).
- Added "application/wasm" mime type to jetty/ide server.
- `cfg.ESM` is now automatic if 'export' or 'import' statements are found.
- Added support for .mjs files.
- Added new file type 'JS-Module'.
- Changed Hybrid samples to use import statements.
- Enabled creation of Python apps from wifi IDE.
- Switched Python Hybrid default to light mode.
- Removed Github feature (more work on wifi ide version needed).
- Added missing imports from many Python samples in docs.
- Html and Hybrid apps no longer allow pinch/zoom/scroll by default.
- Added 'desktop' option to `app.CreateWebView()` methods (enables desktop mode).
- Added `WebView.SetOptions` method so that (most) options can be changed at runtime.

## DS 2.76b1

- Fixed issue with null timer ids when using `app.SetOnError` in Node apps.
- Added missing Bluetooth/Location permissions when `app.DiscoverBtDevices` is used.
- Fixed right-click 'Install' option in wifi ide for ppks.
- Fixed `app.UnzipFile` failure on some devices.
- Added the .mjs MIME mapping to Jetty web server.
- Fixed `cfg.ESM` mode for recent Android WebViews.
- Fixed atob bug breaking pre-encoded plugin strings sent with CallScript method.
- Fixed automatic resize for Hybrid and Python apps on screen rotation.
- Added `ext.deviceName` and `ext.appType` fields to extension object.
- Added appType parameter to `ext_OnProject` callback.
- Fixed using `app.CreateNode` method inside services.
- Fixed `PlayStore.GetPurchases()` not returning 'IAP' types.
- Updated docs theme to look more modern (and match v3 editor).
- Upgraded material icons version for docs and extensions.
- Added `SetWeight( weight, orient )` method to all controls.
- Added `Layout.SetWeightSum( sum )`.
- Switched plugin installer to use Android built-in zip extractor.
- Fixed wiping out of .mjs files when using `cfg.NodeESM` mode.
- Modified NodeJS `os.homedir()` func to return same as `app.RealPath("/Private")`.
- Added (dark) Google group to forum tab.
- Fixed bug stopping demos work after using docs pythons samples.

## DS 2.75b2

- Prevented high CPU/power usage of NodeJS apps.
- Fixed DoEvents to prevent lockups in Node based apps.
- Added 'doevents' option to `app.CopyFolder` (keeps UI alive when copying large folders).
- Fixed 'Simple' Node Native template.

## DS 2.75b1

- Fixed crash when calling `!buildapk` option from Wifi-IDE.
- Added extra 'password' param to `!buildapk` (user.keystore musts exist).
- Added new `!buildaab` command to Wifi-IDE.
- Added 'noHeadless' option to config.json (block TV/Headless mode).
- Fixed `app.SetOnError` method for Node based apps (trap errors to prevent app exit).
- Crypto now uses "AES/GCM/NoPadding" (pass "AES/ECB/PKCS5Padding" to `app.CreateCrypt` for old method).
- Removed old samples tab from Wifi-IDE.
- Removed scanning for 'HeartRate' keyword (related to restricted body sensor permission).
- Fixed missing docs + 90% installation lockup for TV devices.
