From aa29d65d67a133414e63ee500d43177ac15287ef Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 24 Oct 2026 14:24:10 +0200 Subject: [PATCH 01/11] refactor(ui): migrate to the ui-native-components packages Replace every ui-material-* plugin with the @nativescript-community/ui-* ones (button, switch, slider, textfield, textview, dialogs, bottomsheet, snackbar, progress, activityindicator, segmentedbar) so the app and the shared tools components use one set of plugins. - rename `mdbutton` to `uibutton` (kept as an alias for the shared components) and update the css selectors to the new element types - keep the sqlite 3 database wrapper in app/db: the shared one needs sqlite-core 4 - add the Mac Catalyst window helper, the @nativescript/ios runtime for Catalyst and the prepare/run catalyst scripts Co-Authored-By: Claude Sonnet 5.5 --- app/android/camera_scan_activity.ts | 2 +- app/app.android.scss | 2 +- app/app.common.scss | 12 +- app/app.ts | 40 ++- app/components/ModalImportImages.svelte | 12 +- app/components/OAuthWebViewModal.svelte | 2 +- app/components/camera/Camera.svelte | 8 +- app/components/common/CActionBar.svelte | 2 +- app/components/common/ColorPicker.svelte | 6 +- app/components/common/DocumentPicker.svelte | 4 +- .../common/EditNameActionBar.svelte | 4 +- app/components/common/FolderTextView.svelte | 2 +- app/components/common/FolderView.svelte | 4 +- app/components/common/LoadingIndicator.svelte | 2 +- .../common/RemoteFolderTextField.svelte | 2 +- app/components/common/SelectionToolbar.svelte | 4 +- .../common/TransformPagesBottomSheet.svelte | 6 +- app/components/edit/CropEditView.svelte | 8 +- app/components/edit/DocumentEdit.svelte | 22 +- app/components/list/CardListCell.svelte | 2 +- app/components/ocr/OCRDataView.svelte | 6 +- .../ocr/OCRSettingsBottomSheet.svelte | 10 +- app/components/pdf/PDFPreview.svelte | 12 +- app/components/qrcode/CreateBarcode.svelte | 2 +- app/components/security/PasscodeWindow.svelte | 4 +- .../settings/FolderManagementView.svelte | 4 +- app/components/settings/Settings.svelte | 10 +- app/components/settings/StorageView.svelte | 2 +- .../settings/sync/DataSyncSettings.svelte | 2 +- .../settings/sync/ImageSyncSettings.svelte | 4 +- .../settings/sync/OAuthSettingsView.svelte | 4 +- .../settings/sync/PDFSyncSettings.svelte | 6 +- .../sync/SyncFoldersSettingsView.svelte | 2 +- .../settings/sync/SyncListSettings.svelte | 2 +- .../sync/SyncSettingsCollectionView.svelte | 6 +- .../paperless/PaperlessNgxSettingsView.svelte | 2 +- .../sync/webdav/WebdavSettingsView.svelte | 4 +- app/components/view/CardView.svelte | 28 +- app/components/view/DocumentView.svelte | 14 +- app/components/widgets/Chip.svelte | 2 +- app/components/widgets/CreateCard.svelte | 2 +- .../widgets/ExtraFieldPicker.svelte | 4 +- app/db/NSQLDatabase.ts | 78 +++++ app/i18n/en.json | 3 + app/services/documents.ts | 2 +- app/utils/ui/index.android.ts | 4 +- app/utils/ui/index.common.ts | 4 +- nativescript.config.js | 4 +- package.json | 33 +- tsconfig.json | 2 +- typings/ios.d.ts | 3 + vitest.setup.ts | 2 +- yarn.lock | 300 ++++++++++-------- 53 files changed, 425 insertions(+), 288 deletions(-) create mode 100644 app/db/NSQLDatabase.ts diff --git a/app/android/camera_scan_activity.ts b/app/android/camera_scan_activity.ts index 0e9388711..d0d76201d 100644 --- a/app/android/camera_scan_activity.ts +++ b/app/android/camera_scan_activity.ts @@ -1,5 +1,5 @@ import { AppUtilsAndroid } from '@akylas/nativescript-app-utils'; -import { showBottomSheet } from '@nativescript-community/ui-material-bottomsheet/svelte'; +import { showBottomSheet } from '@nativescript-community/ui-bottomsheet/svelte'; import { AndroidActivityBackPressedEventData, AndroidActivityCallbacks, diff --git a/app/app.android.scss b/app/app.android.scss index 3504ca9c7..b10ec4584 100644 --- a/app/app.android.scss +++ b/app/app.android.scss @@ -1,4 +1,4 @@ @import './app.common'; checkbox { - margin-right: -16; + margin-right: 0; } diff --git a/app/app.common.scss b/app/app.common.scss index 2c5bd2b0a..e1081fcc8 100644 --- a/app/app.common.scss +++ b/app/app.common.scss @@ -51,8 +51,8 @@ font-family: $mdiFontFamily; } -mdtextfield, -mdtextview { +textfield, +textview { stroke-color: var(--colorOutline); placeholder-color: var(--colorOutline); color: var(--colorOnBackground); @@ -64,8 +64,8 @@ checkbox { fill-color: var(--colorPrimary); } -mdbutton[variant='flat'], -mdbutton[variant='contained'] { +button[variant='flat'], +button[variant='contained'] { background-color: var(--colorPrimary); color: var(--colorOnPrimary); } @@ -86,7 +86,7 @@ htmllabel { // white-space: normal; } -// mdtextfield { +// textfield { // color: black; // // background-color: white; // // placeholder-color: black; @@ -152,7 +152,7 @@ frame { label, canvaslabel, htmllabel, -mdtextfield, +textfield, .actionBarTitle, .actionBarSubtitle { &:black, diff --git a/app/app.ts b/app/app.ts index e8ecb742f..31f82c8bc 100644 --- a/app/app.ts +++ b/app/app.ts @@ -1,22 +1,23 @@ +import { startWindowHelper } from '@shared/utils/window'; import { GestureRootView, install as installGestures } from '@nativescript-community/gesturehandler'; import { installMixins as installUIMixins } from '@nativescript-community/systemui'; import { overrideSpanAndFormattedString } from '@nativescript-community/text'; import SwipeMenuElement from '@nativescript-community/ui-collectionview-swipemenu/svelte'; import CollectionViewElement from '@nativescript-community/ui-collectionview/svelte'; -import SegmentedBarElement from '@nativescript-community/ui-material-segmentedbar/svelte/SegmentedBarElement'; +import { register as registerAppBar } from '@nativescript-community/ui-appbar/svelte'; import DrawerElement from '@nativescript-community/ui-drawer/svelte'; import { ImagePipeline, ImageViewTraceCategory, getImagePipeline, initialize } from '@nativescript-community/ui-image'; import { installMixins as installColorFilters } from '@nativescript-community/ui-image-colorfilter'; import { Label } from '@nativescript-community/ui-label'; -import { install as installBottomSheets } from '@nativescript-community/ui-material-bottomsheet'; -import { installMixins, themer } from '@nativescript-community/ui-material-core'; +import { install as installBottomSheets } from '@nativescript-community/ui-bottomsheet'; +import { installMixins, themer } from '@nativescript-community/ui-core'; import { Pager } from '@nativescript-community/ui-pager'; import PagerElement from '@nativescript-community/ui-pager/svelte'; import { Application, ApplicationSettings, Frame, NavigatedData, Page, Trace } from '@nativescript/core'; import { startSentry } from '@shared/utils/sentry'; import { showError } from '@shared/utils/showError'; import { CropView } from 'plugin-nativeprocessor/CropView'; -import { FrameElement, PageElement, createElement, navigate, registerElement, registerNativeViewElement } from '@nativescript-community/svelte-native/dom'; +import { FrameElement, NativeElementPropType, PageElement, createElement, navigate, registerElement, registerNativeViewElement } from '@nativescript-community/svelte-native/dom'; import { NestedScrollView } from '@shared/components/NestedScrollView'; import { getCurrentISO3Language, lc } from '~/helpers/locale'; import { start as startThemeHelper } from '~/helpers/theme'; @@ -81,15 +82,19 @@ try { registerNativeViewElement('GridLayout', () => require('@nativescript/core').GridLayout); registerNativeViewElement('ScrollView', () => NestedScrollView as any); registerNativeViewElement('StackLayout', () => require('@nativescript/core').StackLayout); - registerNativeViewElement('Switch', () => require('@nativescript-community/ui-material-switch').Switch); + registerNativeViewElement('Switch', () => require('@nativescript-community/ui-switch').Switch); registerNativeViewElement('Span', () => require('@nativescript/core').Span); - registerNativeViewElement('slider', () => require('@nativescript-community/ui-material-slider').Slider, null, {}, { override: true }); - registerNativeViewElement('textview', () => require('@nativescript-community/ui-material-textview').TextView, null, {}, { override: true }); - registerNativeViewElement('textfield', () => require('@nativescript-community/ui-material-textfield').TextField, null, {}, { override: true }); - registerNativeViewElement('mdbutton', () => require('@nativescript-community/ui-material-button').Button); - registerNativeViewElement('activityIndicator', () => require('@nativescript-community/ui-material-activityindicator').ActivityIndicator); - registerNativeViewElement('progress', () => require('@nativescript-community/ui-material-progress').Progress); + registerNativeViewElement('slider', () => require('@nativescript-community/ui-slider').Slider, null, {}, { override: true }); + registerNativeViewElement('textview', () => require('@nativescript-community/ui-textview').TextView, null, {}, { override: true }); + registerNativeViewElement('textfield', () => require('@nativescript-community/ui-textfield').TextField, null, {}, { override: true }); + registerAppBar(); + registerNativeViewElement('uibutton', () => require('@nativescript-community/ui-button').Button); + registerNativeViewElement('uifloatingactionbutton', () => require('@nativescript-community/ui-floatingactionbutton').FloatingActionButton); + // the shared components still use the mdbutton tag + registerNativeViewElement('mdbutton', () => require('@nativescript-community/ui-button').Button); + registerNativeViewElement('activityIndicator', () => require('@nativescript-community/ui-activityindicator').ActivityIndicator); + registerNativeViewElement('progress', () => require('@nativescript-community/ui-progress').Progress); registerNativeViewElement('label', () => Label); registerNativeViewElement('image', () => require('@nativescript-community/ui-image').Img); registerNativeViewElement('zoomimage', () => require('@nativescript-community/ui-zoomimage').ZoomImg); @@ -103,13 +108,14 @@ try { registerNativeViewElement('gesturerootview', () => require('@nativescript-community/gesturehandler').GestureRootView); registerNativeViewElement('awebview', () => require('@nativescript-community/ui-webview').AWebView); registerNativeViewElement('lottie', () => require('@nativescript-community/ui-lottie').LottieView); + registerNativeViewElement('segmentedbar', () => require('@nativescript-community/ui-segmentedbar').SegmentedBar, null, { items: NativeElementPropType.Array }, { override: true }); + registerNativeViewElement('segmentedbaritem', () => require('@nativescript-community/ui-segmentedbar').SegmentedBarItem, 'items', {}, { override: true }); registerNativeViewElement('pagerindicator', () => require('@nativescript-community/ui-pager-indicator').PagerIndicator); registerNativeViewElement('svgview', () => require('@nativescript-community/ui-svg').SVGView); // registerNativeViewElement('blurview', () => require('@nativescript-community/ui-blurview').BlurView); PagerElement.register(); CollectionViewElement.register(); - SegmentedBarElement.register(); SwipeMenuElement.register(); DrawerElement.register(); const shouldEnableSentry = ApplicationSettings.getBoolean(SETTINGS_ENABLE_CRASH_REPORT, PLAY_STORE_BUILD); @@ -152,6 +158,16 @@ try { Application.on(Application.launchEvent, async () => { // DEV_LOG && console.log('launch'); startThemeHelper(); + startWindowHelper({ + startWidth: 1300, + startHeight: 940, + minWidth: 480, + minHeight: 560, + commands: [ + { id: 'search', title: lc('search'), input: 'f', menu: 'edit' }, + { id: 'preferences', title: lc('preferences'), input: ',', menu: 'preferences' } + ] + }); launched = true; start(); }); diff --git a/app/components/ModalImportImages.svelte b/app/components/ModalImportImages.svelte index 196c413b4..c14414dc9 100644 --- a/app/components/ModalImportImages.svelte +++ b/app/components/ModalImportImages.svelte @@ -107,7 +107,7 @@ - changePage(-1)} />