diff --git a/.gitignore b/.gitignore
index 155dab1..742dab1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
/apps/demo-vue
+/packages/vue/.vitepress/cache
/apps/NativeScriptVueUse-demo
# compiled output
/dist
@@ -43,3 +44,6 @@ Thumbs.db
*.tgz
packages/**/angular/dist
+
+.nx/cache
+.nx/workspace-data
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
index 413ca14..342760a 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -3,3 +3,6 @@
/dist
/coverage
native-src
+
+/.nx/cache
+/.nx/workspace-data
\ No newline at end of file
diff --git a/README.md b/README.md
index 6d1774f..2462bcb 100644
--- a/README.md
+++ b/README.md
@@ -1,56 +1,45 @@
-- [@vallemar/nativescript-clipboard](packages/nativescript-clipboard/README.md)
-- [@vallemar/nativescript-keyboard](packages/nativescript-keyboard/README.md)
-- [@vallemar/nativescript-orientation](packages/nativescript-orientation/README.md)
-- [@vallemar/nativescript-vueuse](packages/nativescript-vueuse/README.md)
+# NativeScript-Use
-# How to use?
+Collection of NativeScript-Use Composition Utilities
-This workspace manages the suite of plugins listed above.
+[Documentation (Vue3)](https://nativescriptuse-vue.netlify.app/)
+
-In general, when in doubt with what to do, just `npm start`.
+This library tries to cover all the `-use` libraries of the frameworks with NativeScript.
+Examples:
+- [VueUse](https://vueuse.org/)
+- [svelte-use](https://svelte-use.vercel.app/)
+- [react-use](https://github.com/streamich/react-use)
+- [solid-use](https://github.com/lxsmnsyc/solid-use)
-## How to add a new package to workspace?
+## `Use`Packages
+- [@nativescript-use/vue (Vue3)](packages/vue/README.md)
-```
-npm run add
-```
+As native dependencies, the native code packages have been created in TS so that the core of `NativeScript-Use` is common. Anyone who wants can contribute to create another savor for example: `@nativescript-use/svelte`.
+
-At the prompt, enter the name of the new package.
+The following plugins are the core of some of the native functionality already being used in `@nativescript-use/vue`, they have been separated so they can be used for any `@nativescript-use/[any_flavor]` flavor and also, so they can be used as individual plugins. inside nativescript
-- This adds a plugin harness in `packages` with the necessary boilerplate to just start developing
-- Updates all demo app flavors to support demoing the new package
-- Adds shared code in `tools/demo` where you can write demo code **once** and share across all demo flavors
-- Updates build tooling to support the new package
-- Updates the `npm start` interactive display
-- Updates the README here to list the new package
+- [@nativescript-use/change-icon](packages/change-icon/README.md)
+- [@nativescript-use/nativescript-clipboard](packages/nativescript-clipboard/README.md)
+- [@nativescript-use/nativescript-intersection-observer](packages/nativescript-intersection-observer/README.md)
+- [@nativescript-use/nativescript-keyboard](packages/nativescript-keyboard/README.md)
+- [@nativescript-use/nativescript-localstorage](packages/nativescript-localstorage/README.md)
+- [@nativescript-use/nativescript-media-query](packages/nativescript-media-query/README.md)
+- [@nativescript-use/nativescript-orientation](packages/nativescript-orientation/README.md)
+- [@nativescript-use/nativescript-task](packages/nativescript-task/README.md)
-## How to add Angular compatibility to a package
+# How to contribute?
-```
-npm run add-angular
-```
+- clone the repository.
+- run: `npm run setup`
+- clone app in folder `/apps/` for test and preview in docs: `git clone https://github.com/NativeScript-Use/demo-vue.git`
+- run app in root folder: `npm run demo:vue:android` or `npm run demo:vue:ios`
+- add your changes in `./packages/vue`
-At the prompt, enter the name of the package to add an `angular` folder to it with the necessary boilerplate to provide Angular support to the package.
+Now all the changes that you add will make the application restart and you will be able to add see the effect of your changes
-## How to focus on just 1 package to develop in isolation
+For more information you can enter the [NativeScript discord server](https://discord.com/invite/RgmpGky9GR)!
-```
-npm start
-```
-
-- Choose the focus commands for the package you wish to focus on and hit enter.
-- All the demo app's will be updated to isolate that 1 package and for supported IDE's (currently VS Code), the source code will also become isolated in the workspace.
-
-Note: *good to always clean the demo you plan to run after focusing. (You can clean any demo from `npm start` as well)*
-
-## How to publish packages?
-
-```
-npm run publish-packages
-```
-
-- You will be prompted for the package names to publish. Leaving blank and hitting enter will publish them all.
-- You will then be prompted for the version to use. Leaving blank will auto bump the patch version (it also handles prerelease types like alpha, beta, rc, etc. - It even auto tags the corresponding prelease type on npm).
-- You will then be given a brief sanity check 🧠😊
Made with ❤️
diff --git a/apps/demo/.gitignore b/apps/demo/.gitignore
deleted file mode 100644
index 407ded9..0000000
--- a/apps/demo/.gitignore
+++ /dev/null
@@ -1,42 +0,0 @@
-# NativeScript
-hooks/
-node_modules/
-platforms/
-
-# NativeScript Template
-*.js.map
-*.js
-!webpack.config.js
-
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# General
-.DS_Store
-.AppleDouble
-.LSOverride
-.idea
-.cloud
-.project
-tmp/
-typings/
-
-# misc
-npm-debug.log
-
-# app
-!*.d.ts
-!src/assets/fontawesome.min.css
-/report/
-.nsbuildinfo
-/temp/
-/src/tns_modules/
-
-# app uses platform specific scss which can inadvertently get renamed which will cause problems
-app/app.scss
-
-package-lock.json
diff --git a/apps/demo/nativescript.config.ts b/apps/demo/nativescript.config.ts
deleted file mode 100644
index a0a66bc..0000000
--- a/apps/demo/nativescript.config.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { NativeScriptConfig } from '@nativescript/core';
-
-export default {
- id: 'org.nativescript.plugindemo',
- appResourcesPath: '../../tools/assets/App_Resources',
- android: {
- v8Flags: '--expose_gc',
- markingMode: 'none',
- },
- appPath: 'src',
- cli: {
- packageManager: 'npm'
- }
-} as NativeScriptConfig;
diff --git a/apps/demo/package.json b/apps/demo/package.json
deleted file mode 100644
index 1bd86c9..0000000
--- a/apps/demo/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "main": "./src/app.ts",
- "description": "NativeScript Application",
- "license": "SEE LICENSE IN ",
- "repository": "",
- "dependencies": {
- "@nativescript/core": "file:../../node_modules/@nativescript/core",
- "@vallemar/nativescript-vueuse": "file:../../packages/nativescript-vueuse",
- "@vallemar/nativescript-orientation": "file:../../packages/nativescript-orientation",
- "@vallemar/nativescript-keyboard": "file:../../packages/nativescript-keyboard",
- "@vallemar/nativescript-clipboard": "file:../../packages/nativescript-clipboard"
- },
- "devDependencies": {
- "@nativescript/android": "~8.4.0",
- "@nativescript/ios": "~8.4.0"
- }
-}
diff --git a/apps/demo/project.json b/apps/demo/project.json
deleted file mode 100644
index ddda9cc..0000000
--- a/apps/demo/project.json
+++ /dev/null
@@ -1,61 +0,0 @@
-{
- "name": "demo",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "sourceRoot": "apps/demo/src",
- "projectType": "application",
- "prefix": "demo",
- "targets": {
- "build": {
- "executor": "@nativescript/nx:build",
- "options": {
- "noHmr": true,
- "production": true,
- "uglify": true,
- "release": true,
- "forDevice": true
- },
- "dependsOn": [
- {
- "target": "build.all",
- "projects": "dependencies"
- }
- ]
- },
- "ios": {
- "executor": "@nativescript/nx:build",
- "options": {
- "platform": "ios"
- },
- "dependsOn": [
- {
- "target": "build.all",
- "projects": "dependencies"
- }
- ]
- },
- "android": {
- "executor": "@nativescript/nx:build",
- "options": {
- "platform": "android"
- },
- "dependsOn": [
- {
- "target": "build.all",
- "projects": "dependencies"
- }
- ]
- },
- "clean": {
- "executor": "@nativescript/nx:build",
- "options": {
- "clean": true
- }
- },
- "lint": {
- "executor": "@nrwl/linter:eslint",
- "options": {
- "lintFilePatterns": ["apps/demo/**/*.ts"]
- }
- }
- }
-}
diff --git a/apps/demo/src/app-root.xml b/apps/demo/src/app-root.xml
deleted file mode 100644
index 54e70d9..0000000
--- a/apps/demo/src/app-root.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/apps/demo/src/app.scss b/apps/demo/src/app.scss
deleted file mode 100644
index d0ac013..0000000
--- a/apps/demo/src/app.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import 'nativescript-theme-core/scss/light';
-@import 'nativescript-theme-core/scss/index';
\ No newline at end of file
diff --git a/apps/demo/src/app.ts b/apps/demo/src/app.ts
deleted file mode 100644
index a4c5c52..0000000
--- a/apps/demo/src/app.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { Application } from '@nativescript/core';
-
-Application.run({ moduleName: 'app-root' });
diff --git a/apps/demo/src/main-page.ts b/apps/demo/src/main-page.ts
deleted file mode 100644
index 89e6b7a..0000000
--- a/apps/demo/src/main-page.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { EventData, Page } from '@nativescript/core';
-import { MainViewModel } from "./main-view-model";
-
-export function navigatingTo(args: EventData) {
- const page = args.object;
- page.bindingContext = new MainViewModel();
-}
diff --git a/apps/demo/src/main-page.xml b/apps/demo/src/main-page.xml
deleted file mode 100644
index e4a737a..0000000
--- a/apps/demo/src/main-page.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apps/demo/src/main-view-model.ts b/apps/demo/src/main-view-model.ts
deleted file mode 100644
index 394f469..0000000
--- a/apps/demo/src/main-view-model.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Observable, Frame } from '@nativescript/core';
-
-export class MainViewModel extends Observable {
-
- viewDemo(args) {
- Frame.topmost().navigate({
- moduleName: `plugin-demos/${args.object.text}`,
- });
- }
-}
diff --git a/apps/demo/src/plugin-demos/.gitkeep b/apps/demo/src/plugin-demos/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/apps/demo/src/plugin-demos/nativescript-clipboard.ts b/apps/demo/src/plugin-demos/nativescript-clipboard.ts
deleted file mode 100644
index 010a352..0000000
--- a/apps/demo/src/plugin-demos/nativescript-clipboard.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Observable, EventData, Page } from '@nativescript/core';
-import { DemoSharedNativescriptClipboard } from '@demo/shared';
-import { } from '@vallemar/nativescript-clipboard';
-
-export function navigatingTo(args: EventData) {
- const page = args.object;
- page.bindingContext = new DemoModel();
-}
-
-export class DemoModel extends DemoSharedNativescriptClipboard {
-
-}
diff --git a/apps/demo/src/plugin-demos/nativescript-clipboard.xml b/apps/demo/src/plugin-demos/nativescript-clipboard.xml
deleted file mode 100644
index 101ab44..0000000
--- a/apps/demo/src/plugin-demos/nativescript-clipboard.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apps/demo/src/plugin-demos/nativescript-keyboard.ts b/apps/demo/src/plugin-demos/nativescript-keyboard.ts
deleted file mode 100644
index a371db3..0000000
--- a/apps/demo/src/plugin-demos/nativescript-keyboard.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Observable, EventData, Page } from '@nativescript/core';
-import { DemoSharedNativescriptKeyboard } from '@demo/shared';
-import { } from '@vallemar/nativescript-keyboard';
-
-export function navigatingTo(args: EventData) {
- const page = args.object;
- page.bindingContext = new DemoModel();
-}
-
-export class DemoModel extends DemoSharedNativescriptKeyboard {
-
-}
diff --git a/apps/demo/src/plugin-demos/nativescript-keyboard.xml b/apps/demo/src/plugin-demos/nativescript-keyboard.xml
deleted file mode 100644
index 05ccbf1..0000000
--- a/apps/demo/src/plugin-demos/nativescript-keyboard.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apps/demo/src/plugin-demos/nativescript-orientation.ts b/apps/demo/src/plugin-demos/nativescript-orientation.ts
deleted file mode 100644
index a0e4b92..0000000
--- a/apps/demo/src/plugin-demos/nativescript-orientation.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Observable, EventData, Page } from '@nativescript/core';
-import { DemoSharedNativescriptOrientation } from '@demo/shared';
-import { } from '@vallemar/nativescript-orientation';
-
-export function navigatingTo(args: EventData) {
- const page = args.object;
- page.bindingContext = new DemoModel();
-}
-
-export class DemoModel extends DemoSharedNativescriptOrientation {
-
-}
diff --git a/apps/demo/src/plugin-demos/nativescript-orientation.xml b/apps/demo/src/plugin-demos/nativescript-orientation.xml
deleted file mode 100644
index 79e463d..0000000
--- a/apps/demo/src/plugin-demos/nativescript-orientation.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apps/demo/src/plugin-demos/nativescript-vueuse.ts b/apps/demo/src/plugin-demos/nativescript-vueuse.ts
deleted file mode 100644
index 2ca7b5f..0000000
--- a/apps/demo/src/plugin-demos/nativescript-vueuse.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Observable, EventData, Page } from '@nativescript/core';
-import { DemoSharedNativescriptVueuse } from '@demo/shared';
-import { } from '@vallemar/nativescript-vueuse';
-
-export function navigatingTo(args: EventData) {
- const page = args.object;
- page.bindingContext = new DemoModel();
-}
-
-export class DemoModel extends DemoSharedNativescriptVueuse {
-
-}
diff --git a/apps/demo/src/plugin-demos/nativescript-vueuse.xml b/apps/demo/src/plugin-demos/nativescript-vueuse.xml
deleted file mode 100644
index c03652f..0000000
--- a/apps/demo/src/plugin-demos/nativescript-vueuse.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apps/demo/tsconfig.json b/apps/demo/tsconfig.json
deleted file mode 100644
index 4f3f390..0000000
--- a/apps/demo/tsconfig.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "rootDirs": [
- ".",
- "../.."
- ],
- "baseUrl": ".",
- "paths": {
- "~/*": [
- "src/*"
- ],
- "@demo/shared": [
- "../../tools/demo/index.ts"
- ],
- "@vallemar/*": [
- "../../packages/*"
- ]
- }
- }
-}
diff --git a/apps/demo/webpack.config.js b/apps/demo/webpack.config.js
deleted file mode 100644
index 05d00ce..0000000
--- a/apps/demo/webpack.config.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const webpack = require('@nativescript/webpack');
-const { resolve } = require('path');
-
-module.exports = (env) => {
-
- webpack.init(env);
- webpack.useConfig('typescript');
-
- webpack.chainWebpack((config) => {
- // shared demo code
- config.resolve.alias.set('@demo/shared', resolve(__dirname, '..', '..', 'tools', 'demo'));
- });
-
- // Example if you need to share images across demo apps:
- // webpack.Utils.addCopyRule({
- // from: '../../../tools/images',
- // to: 'images',
- // context: webpack.Utils.project.getProjectFilePath('node_modules')
- // });
-
- return webpack.resolveConfig();
-};
diff --git a/nx.json b/nx.json
index 6c4d88d..7fd1e92 100644
--- a/nx.json
+++ b/nx.json
@@ -1,60 +1,42 @@
{
- "npmScope": "vallemar",
- "affected": {
- "defaultBase": "master"
- },
"workspaceLayout": {
"appsDir": "apps",
"libsDir": "packages"
},
"tasksRunnerOptions": {
"default": {
- "runner": "nx/tasks-runners/default",
"options": {
- "cacheableOperations": [
- "build",
- "build.all",
- "lint",
- "test",
- "e2e"
- ],
- "runtimeCacheInputs": [
- "node -v"
- ],
- "parallel": 1,
- "useDaemonProcess": false
+ "runtimeCacheInputs": ["node -v"]
}
}
},
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"namedInputs": {
- "default": [
- "{projectRoot}/**/*",
- "sharedGlobals"
- ],
- "sharedGlobals": [
- "{workspaceRoot}/workspace.json",
- "{workspaceRoot}/tsconfig.base.json",
- "{workspaceRoot}/tslint.json",
- "{workspaceRoot}/nx.json"
- ],
- "production": [
- "default",
- "!{projectRoot}/.eslintrc.json"
- ]
+ "default": ["{projectRoot}/**/*", "sharedGlobals"],
+ "sharedGlobals": ["{workspaceRoot}/workspace.json", "{workspaceRoot}/tsconfig.base.json", "{workspaceRoot}/tslint.json", "{workspaceRoot}/nx.json"],
+ "production": ["default", "!{projectRoot}/.eslintrc.json"]
},
"targetDefaults": {
"build": {
- "inputs": [
- "production",
- "^production"
- ]
+ "inputs": ["production", "^production"],
+ "cache": true
},
"lint": {
- "inputs": [
- "default",
- "{workspaceRoot}/.eslintrc.json"
- ]
+ "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
+ "cache": true
+ },
+ "build.all": {
+ "cache": true
+ },
+ "test": {
+ "cache": true
+ },
+ "e2e": {
+ "cache": true
}
- }
+ },
+ "useDaemonProcess": false,
+ "parallel": 1,
+ "defaultBase": "master",
+ "useLegacyCache": true
}
diff --git a/package.json b/package.json
index 74923f0..509af95 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.0.0",
"license": "MIT",
"scripts": {
- "postinstall": "husky install && npx ts-patch install",
+ "postinstall": "husky install && npx ts-patch install && patch-package",
"setup": "npx rimraf node_modules package-lock.json dist tmp yarn.lock && yarn config set ignore-engines true && ns package-manager set npm && yarn",
"start": "nps",
"add": "nx g @nativescript/plugin-tools:add-package",
@@ -13,24 +13,37 @@
"sync-packages-with-demos": "nx g @nativescript/plugin-tools:sync-packages-with-demos",
"remove-package": "nx g @nativescript/plugin-tools:remove-package",
"add-demo": "nx g @nativescript/plugin-tools:add-demo",
- "ts-vue": "cd packages/nativescript-vueuse && npx tsc --watch",
- "build:all": "nx run-many --target=build.all --all",
- "demo:android": "cd apps/demo-vue && npm run android",
- "demo:ios": "cd apps/demo-vue && npm run ios"
+ "ts-vue": "cd packages/vue && npx tsc --watch",
+ "build:all": "nx run-many --target=build.all --all --verbose --skip-nx-cache && node scripts/copy-packages.ts",
+ "postbuild": "node scripts/copy-packages.ts",
+ "build:vue": "nx run-many --target=vue ",
+ "demo:vue:android": "npx nx run demo-vue:android",
+ "demo:vue:ios": "npx nx run demo-vue:ios",
+ "docs:dev": "vitepress dev packages/vue",
+ "docs:build": "vitepress build packages/vue ",
+ "docs:preview": "vitepress preview packages/vue"
},
- "workspaces":["/packages/*", "/apps/*"],
+ "workspaces": [
+ "/packages/*",
+ "/apps/*"
+ ],
"private": true,
"devDependencies": {
- "@nativescript/core": "~8.5.0",
- "@nativescript/plugin-tools": "5.1.0",
+ "@nativescript-use/vue": "^0.0.5",
+ "@nativescript/core": "~8.9.0",
+ "@nativescript/plugin-tools": "5.5.1",
"@nativescript/tailwind": "^2.0.1",
- "@nativescript/types": "~8.5.0",
- "@nativescript/webpack": "^5.0.15",
+ "@nativescript/types": "~8.9.0",
+ "@nativescript/webpack": "^5.0.23",
+ "autoprefixer": "^10.4.14",
"husky": "^8.0.0",
"nativescript-vue": "3.0.0-beta.8",
- "ng-packagr": "^15.0.0",
+ "ng-packagr": "^19.2.0",
+ "patch-package": "~6.4.0",
+ "postcss": "^8.4.24",
"tailwindcss": "^3.3.2",
- "typescript": "~4.8.0"
+ "typescript": "~5.6.0",
+ "vitepress": "^1.6.3"
},
"lint-staged": {
"**/*.{js,ts,scss,json,html}": [
diff --git a/apps/demo/.eslintrc.json b/packages/change-icon/.eslintrc.json
similarity index 100%
rename from apps/demo/.eslintrc.json
rename to packages/change-icon/.eslintrc.json
diff --git a/packages/change-icon/README.md b/packages/change-icon/README.md
new file mode 100644
index 0000000..b4a515d
--- /dev/null
+++ b/packages/change-icon/README.md
@@ -0,0 +1,224 @@
+# @nativescript-use/change-icon
+
+Programmatically change the application icon.
+
+## Install
+```javascript
+npm install @nativescript-use/change-icon
+```
+
+## Configuration
+
+### Android
+
+To begin, we must define our icons in `App_Resources/Android/src/main/res`, we recommend the page https://icon.kitchen/ to generate the icons for our application. This document will create 3 icons for the sample:
+- Default Icon.
+- Dark icon.
+- Cafe icon.
+
+1. Generate the icons and add them to `App_Resources/Android/src/main/res/mipmap`.
+
+- ic_launcher_foreground_[default|dark|cafe].png (`Icon`)
+- ic_launcher_background__[default|dark|cafe].png (`Icon Background`)
+
+1. Add the `adaptive-icon` to your `mipmap-anydpi-v26` folder inside `App_Resources/Android/src/main/res/`.
+
+- `mipmap-anydpi-v26/ic_launcher_default.xml`
+
+```xml
+
+
+
+
+
+```
+
+- `mipmap-anydpi-v26/ic_launcher_dark.xml`
+```xml
+
+
+
+
+
+```
+- `mipmap-anydpi-v26/ic_launcher_cafe.xml`
+```xml
+
+
+
+
+
+```
+
+3. Add `activity-alias` to our `AndroidManifest.xml`. To change the icon in android we need to specify an `activity-alias` in `AndroidManifest.xml` plus one for the default icon, so for this example we will have 3 activity-aliases in our manifest:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Note here the important things from the previous code:
+
+- Removed ` ` from the main activity `activity`.
+- We have 3 `activity-alias`, for Default, Dark and Cafe.
+- Activity alias of `activity-alias` of `MainActivityDefault` has `android:enabled="true"` by default.
+- All other `activity-aliases` have `android:enabled="false"`
+- `android:name` of the `activity-alias` tags must always have the format `.MainActivity[The name we will use to change]`, in this case: `MainActivityDefault`, `MainActivityDark`, `MainActivityCafe`.
+- `android:icon` and `android:roundIcon` have the icon we added earlier.
+- `android:targetActivity` has the value of the main activity, default for NativeScript: `com.tns.NativeScriptActivity`.
+
+
+### iOS
+
+To begin, we must define our icons in `App_Resources/iOS`, we recommend the page https://icon.kitchen/ to generate the icons for our application. This document will create 3 icons for the sample:
+- Default Icon.
+- Dark icon.
+- Cafe icon.
+
+1. Have the Default icon in the `App_Resources/iOS/Assets.xcassets/AppIcon.appiconset` folder
+2. Generate the icons and add them to `App_Resources/iOS`.
+
+- [Dark|Cafe]@x2.png (120x120 Dimensions)
+- [Dark|Cafe]@x3.png (180x180 Dimensions)
+
+3. Add in `Info.plist` (`App_Resources/iOS/Info.plist`) the following code to indicate which is the default and which are the alternatives:
+
+```xml
+CFBundleIcons
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ Default
+
+ UIPrerenderedIcon
+
+
+ CFBundleAlternateIcons
+
+ Dark
+
+ CFBundleIconFiles
+
+ Dark
+
+ UIPrerenderedIcon
+
+
+ Cafe
+
+ CFBundleIconFiles
+
+ Cafe
+
+ UIPrerenderedIcon
+
+
+
+
+```
+
+
+### Usage
+
+You just have to import the library and use the available methods
+- `getCurrent()`
+- `reset()`
+- `change("NameOfIcon")`
+
+```ts
+import { changeIcon } from "@nativescript-use/change-icon"
+
+function changeIconToDark(){
+ changeIcon.change("Dark");
+}
+
+function changeIconToCafe(){
+ changeIcon.change("Cafe");
+}
+
+function changeIconToDefault(){
+ changeIcon.reset();
+}
+
+function getCurrentIcon(){
+ return changeIcon.getCurrent(); // "Default" | "Dark" | "Cafe"
+}
+
+
+```
+## License
+
+Apache License Version 2.0
diff --git a/packages/change-icon/index.android.ts b/packages/change-icon/index.android.ts
new file mode 100644
index 0000000..4857d57
--- /dev/null
+++ b/packages/change-icon/index.android.ts
@@ -0,0 +1,51 @@
+import { Utils } from '@nativescript/core';
+import PackageManager = android.content.pm.PackageManager;
+
+const startNameActivity = 'MainActivity';
+
+export const changeIcon = {
+ reset() {
+ changeIcon.change(null);
+ },
+ getCurrent() {
+ const activity = Utils.android.getCurrentActivity();
+ if (activity == null) {
+ return 'ANDROID:Error';
+ }
+
+ const activityName = activity.getComponentName().getClassName();
+ if (activityName.endsWith(startNameActivity) || activityName === 'com.tns.NativeScriptActivity') {
+ return 'Default';
+ }
+
+ const activityNameSplit = activityName.split(startNameActivity);
+ if (activityNameSplit.length != 2) {
+ return 'ANDROID:UNEXPECTED_COMPONENT_CLASS';
+ }
+
+ return activityNameSplit[1];
+ },
+ change(icon: string | null) {
+ const currentIcon = changeIcon.getCurrent();
+ if (currentIcon === icon) {
+ console.log('ICON_ALREADY_USED');
+ return;
+ }
+
+ if (currentIcon === 'ANDROID:UNEXPECTED_COMPONENT_CLASS' || currentIcon === 'ANDROID:Error') {
+ console.log(currentIcon);
+ return;
+ }
+
+ let newIcon = icon;
+ if (!icon || icon === '' || icon === 'Default') {
+ newIcon = 'Default';
+ }
+ const manager = Utils.android.getCurrentActivity().getPackageManager();
+ //Disable
+ manager.setComponentEnabledSetting(new android.content.ComponentName(Utils.android.getCurrentActivity(), `${Utils.android.getApplicationContext().getPackageName()}.${startNameActivity}${changeIcon.getCurrent()}`), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+
+ //Enable
+ manager.setComponentEnabledSetting(new android.content.ComponentName(Utils.android.getCurrentActivity(), `${Utils.android.getApplicationContext().getPackageName()}.${startNameActivity}${newIcon}`), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+ },
+};
diff --git a/packages/change-icon/index.d.ts b/packages/change-icon/index.d.ts
new file mode 100644
index 0000000..be72f10
--- /dev/null
+++ b/packages/change-icon/index.d.ts
@@ -0,0 +1,5 @@
+export declare const changeIcon: {
+ reset(): void;
+ getCurrent(): string;
+ change(icon: string | null): void;
+};
diff --git a/packages/change-icon/index.ios.ts b/packages/change-icon/index.ios.ts
new file mode 100644
index 0000000..b22488e
--- /dev/null
+++ b/packages/change-icon/index.ios.ts
@@ -0,0 +1,21 @@
+export const changeIcon = {
+ reset() {
+ changeIcon.change(null);
+ },
+ getCurrent() {
+ return UIApplication.sharedApplication.alternateIconName ?? 'Default';
+ },
+ change(icon: string | null) {
+ if (changeIcon.getCurrent() === icon) {
+ console.log('ICON_ALREADY_USED');
+ return;
+ }
+
+ let newIcon: string | null = icon;
+ if (!icon || icon === '' || icon === 'Default') {
+ newIcon = null;
+ }
+
+ UIApplication.sharedApplication.setAlternateIconNameCompletionHandler(newIcon, null);
+ },
+};
diff --git a/packages/nativescript-vueuse/package.json b/packages/change-icon/package.json
similarity index 52%
rename from packages/nativescript-vueuse/package.json
rename to packages/change-icon/package.json
index cc03176..96e729a 100644
--- a/packages/nativescript-vueuse/package.json
+++ b/packages/change-icon/package.json
@@ -1,6 +1,6 @@
{
- "name": "@vallemar/nativescript-vueuse",
- "version": "1.0.0",
+ "name": "@nativescript-use/change-icon",
+ "version": "0.0.4",
"description": "Add a plugin description",
"main": "index",
"typings": "index.d.ts",
@@ -10,14 +10,9 @@
"android": "6.0.0"
}
},
- "dependencies": {
- "@vallemar/nativescript-orientation": "0.0.1",
- "@vallemar/nativescript-keyboard": "0.0.1",
- "@vallemar/nativescript-clipboard": "0.0.1"
- },
"repository": {
"type": "git",
- "url": "https://github.com/NativeScript/plugins.git"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
},
"keywords": [
"NativeScript",
@@ -27,14 +22,14 @@
"Android"
],
"author": {
- "name": "Juan de Dios Matínez Vallejo",
+ "name": "Juan de Dios Martínez Vallejo",
"email": "oss@nativescript.org"
},
"bugs": {
- "url": "https://github.com/NativeScript/plugins/issues"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
},
"license": "Apache-2.0",
- "homepage": "https://github.com/NativeScript/plugins",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
"readmeFilename": "README.md",
"bootstrapper": "@nativescript/plugin-seed"
}
diff --git a/packages/change-icon/project.json b/packages/change-icon/project.json
new file mode 100644
index 0000000..b64afe9
--- /dev/null
+++ b/packages/change-icon/project.json
@@ -0,0 +1,66 @@
+{
+ "name": "change-icon",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "library",
+ "sourceRoot": "packages/change-icon",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "options": {
+ "outputPath": "dist/packages/change-icon",
+ "tsConfig": "packages/change-icon/tsconfig.json",
+ "packageJson": "packages/change-icon/package.json",
+ "main": "packages/change-icon/index.d.ts",
+ "generatePackageJson": false,
+ "assets": [
+ "packages/change-icon/*.md",
+ "packages/change-icon/index.d.ts",
+ "LICENSE",
+ {
+ "glob": "**/*",
+ "input": "packages/change-icon/platforms/",
+ "output": "./platforms/"
+ }
+ ],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ }
+ ]
+ }
+ },
+ "build.all": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["node tools/scripts/build-finish.ts change-icon"],
+ "parallel": false
+ },
+ "outputs": ["dist/packages/change-icon"],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ },
+ {
+ "target": "build",
+ "projects": "self"
+ }
+ ]
+ },
+ "focus": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages change-icon"],
+ "parallel": false
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": ["packages/change-icon/**/*.ts"]
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/apps/demo/references.d.ts b/packages/change-icon/references.d.ts
similarity index 100%
rename from apps/demo/references.d.ts
rename to packages/change-icon/references.d.ts
diff --git a/packages/nativescript-vueuse/tsconfig.json b/packages/change-icon/tsconfig.json
similarity index 75%
rename from packages/nativescript-vueuse/tsconfig.json
rename to packages/change-icon/tsconfig.json
index 84d5771..aed7323 100644
--- a/packages/nativescript-vueuse/tsconfig.json
+++ b/packages/change-icon/tsconfig.json
@@ -5,5 +5,5 @@
"rootDir": "."
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "angular"],
- "include": ["**/*.ts", "./src/**/*.ts", "references.d.ts"]
+ "include": ["**/*.ts", "references.d.ts"]
}
diff --git a/packages/nativescript-clipboard/README.md b/packages/nativescript-clipboard/README.md
index 6f96449..ee08871 100644
--- a/packages/nativescript-clipboard/README.md
+++ b/packages/nativescript-clipboard/README.md
@@ -1,12 +1,39 @@
-# @vallemar/nativescript-clipboard
+# @nativescript-use/nativescript-clipboard
```javascript
-npm install @vallemar/nativescript-clipboard
+npm install @nativescript-use/nativescript-clipboard
```
## Usage
-// TODO
+```ts
+import { Clipboard } from "@nativescript-use/nativescript-clipboard"
+
+const clipboard = new Clipboard();
+
+// Copy text
+clipboard.copy("My text");
+
+// Read Clipboard
+const currentClipboardValue = clipboard.read();
+
+// Add listener
+clipboard.onCopy((textCopied: string) =>{
+ console.log(textCopied)
+});
+// Remove listener
+clipboard.offCopy();
+```
+
+Type declaration
+```ts
+export declare class Clipboard {
+ abstract onCopy(callback: (text: string) => void): void
+ abstract offCopy(): void
+ abstract copy(text: string): boolean
+ abstract read(): string
+}
+```
## License
diff --git a/packages/nativescript-clipboard/index.android.ts b/packages/nativescript-clipboard/index.android.ts
index 24e41b0..d470e20 100644
--- a/packages/nativescript-clipboard/index.android.ts
+++ b/packages/nativescript-clipboard/index.android.ts
@@ -1,47 +1,43 @@
-import { Utils } from "@nativescript/core";
-import { ClipboardBase } from "./common";
+import { Utils } from '@nativescript/core';
+import { ClipboardBase } from './common';
export class Clipboard extends ClipboardBase {
-
- protected clipboard: android.content.ClipboardManager;
-
- constructor() {
- super();
- this.clipboard = Utils.android.getApplicationContext().getSystemService(android.content.Context.CLIPBOARD_SERVICE);
- }
-
- onCopy(callback: (text: string) => void): void {
- this.offCopy();
- let THRESHOLD_MS = 50;
- let enableCallback = true;
- this.listener = new android.content.ClipboardManager.OnPrimaryClipChangedListener({
- onPrimaryClipChanged: () => {
- if (enableCallback)
- callback(this.clipboard.getPrimaryClip().getItemAt(0)?.getText()?.toString());
- enableCallback = false;
- setTimeout(() => {
- enableCallback = true;
- }, THRESHOLD_MS);
- },
- });
- this.clipboard.addPrimaryClipChangedListener(this.listener)
- }
-
- offCopy(): void {
- if (this.listener)
- this.clipboard.removePrimaryClipChangedListener(this.listener)
- }
-
- copy(text: string): boolean {
- const clip = android.content.ClipData.newPlainText("App clipboard data", text);
- this.clipboard.setPrimaryClip(clip);
- return true
- }
-
- read(): string {
- const item = this.clipboard.getPrimaryClip().getItemAt(0);
- let content = item.getText().toString();
- return content || "";
- }
-
-}
\ No newline at end of file
+ protected clipboard: android.content.ClipboardManager;
+
+ constructor() {
+ super();
+ this.clipboard = Utils.android.getApplicationContext().getSystemService(android.content.Context.CLIPBOARD_SERVICE);
+ }
+
+ onCopy(callback: (text: string) => void): void {
+ this.offCopy();
+ let THRESHOLD_MS = 50;
+ let enableCallback = true;
+ this.listener = new android.content.ClipboardManager.OnPrimaryClipChangedListener({
+ onPrimaryClipChanged: () => {
+ if (enableCallback) callback(this.clipboard.getPrimaryClip()?.getItemAt(0)?.getText()?.toString());
+ enableCallback = false;
+ setTimeout(() => {
+ enableCallback = true;
+ }, THRESHOLD_MS);
+ },
+ });
+ this.clipboard.addPrimaryClipChangedListener(this.listener);
+ }
+
+ offCopy(): void {
+ if (this.listener) this.clipboard.removePrimaryClipChangedListener(this.listener);
+ }
+
+ copy(text: string): boolean {
+ const clip = android.content.ClipData.newPlainText('App clipboard data', text);
+ this.clipboard.setPrimaryClip(clip);
+ return true;
+ }
+
+ read(): string {
+ const item = this.clipboard.getPrimaryClip()?.getItemAt(0);
+ let content = item?.getText().toString();
+ return content || '';
+ }
+}
diff --git a/packages/nativescript-clipboard/package.json b/packages/nativescript-clipboard/package.json
index bd3e283..a4ddc29 100644
--- a/packages/nativescript-clipboard/package.json
+++ b/packages/nativescript-clipboard/package.json
@@ -1,6 +1,6 @@
{
- "name": "@vallemar/nativescript-clipboard",
- "version": "1.0.0",
+ "name": "@nativescript-use/nativescript-clipboard",
+ "version": "0.0.3",
"description": "Add a plugin description",
"main": "index",
"typings": "index.d.ts",
@@ -12,7 +12,7 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/NativeScript/plugins.git"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
},
"keywords": [
"NativeScript",
@@ -26,10 +26,10 @@
"email": "oss@nativescript.org"
},
"bugs": {
- "url": "https://github.com/NativeScript/plugins/issues"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
},
"license": "Apache-2.0",
- "homepage": "https://github.com/NativeScript/plugins",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
"readmeFilename": "README.md",
"bootstrapper": "@nativescript/plugin-seed"
}
diff --git a/packages/nativescript-clipboard/project.json b/packages/nativescript-clipboard/project.json
index 3186adc..24a3abe 100644
--- a/packages/nativescript-clipboard/project.json
+++ b/packages/nativescript-clipboard/project.json
@@ -5,12 +5,13 @@
"sourceRoot": "packages/nativescript-clipboard",
"targets": {
"build": {
- "executor": "@nrwl/js:tsc",
+ "executor": "@nx/js:tsc",
"options": {
"outputPath": "dist/packages/nativescript-clipboard",
"tsConfig": "packages/nativescript-clipboard/tsconfig.json",
"packageJson": "packages/nativescript-clipboard/package.json",
"main": "packages/nativescript-clipboard/index.d.ts",
+ "generatePackageJson": false,
"assets": [
"packages/nativescript-clipboard/*.md",
"packages/nativescript-clipboard/index.d.ts",
@@ -32,14 +33,10 @@
"build.all": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "node tools/scripts/build-finish.ts nativescript-clipboard"
- ],
+ "commands": ["node tools/scripts/build-finish.ts nativescript-clipboard"],
"parallel": false
},
- "outputs": [
- "dist/packages/nativescript-clipboard"
- ],
+ "outputs": ["dist/packages/nativescript-clipboard"],
"dependsOn": [
{
"target": "build.all",
@@ -54,18 +51,14 @@
"focus": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "nx g @nativescript/plugin-tools:focus-packages nativescript-clipboard"
- ],
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-clipboard"],
"parallel": false
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
- "lintFilePatterns": [
- "packages/nativescript-clipboard/**/*.ts"
- ]
+ "lintFilePatterns": ["packages/nativescript-clipboard/**/*.ts"]
}
}
},
diff --git a/packages/nativescript-vueuse/.eslintrc.json b/packages/nativescript-intersection-observer/.eslintrc.json
similarity index 100%
rename from packages/nativescript-vueuse/.eslintrc.json
rename to packages/nativescript-intersection-observer/.eslintrc.json
diff --git a/packages/nativescript-intersection-observer/README.md b/packages/nativescript-intersection-observer/README.md
new file mode 100644
index 0000000..64ae369
--- /dev/null
+++ b/packages/nativescript-intersection-observer/README.md
@@ -0,0 +1,37 @@
+# @nativescript-use/nativescript-intersection-observer
+
+```javascript
+npm install @nativescript-use/nativescript-intersection-observer
+```
+
+## Usage
+
+```ts
+import { IntersectionObserver } from "@nativescript-use/nativescript-intersection-observer"
+
+const intersectionObserver = new IntersectionObserver();
+
+// Track if `targetView` is visible
+intersectionObserver.track(targetView, scollView, (isVisible) => {
+ console.log("isVisible: " + isVisible);
+})
+
+// Stop track
+intersectionObserver.stopTrack();
+
+// Check if is visible view
+const isVisible = intersectionObserver.isVisible(targetView, scollView);
+```
+
+Type declaration
+```ts
+export declare class IntersectionObserver {
+ track(view: View, parentView: ScrollView, callback: (isVisible: boolean) => void): void;
+ topTrack(parentView: ScrollView): void
+ isVisible(view: View, parentView?: View): boolean;
+}
+```
+
+## License
+
+Apache License Version 2.0
diff --git a/packages/nativescript-intersection-observer/common.ts b/packages/nativescript-intersection-observer/common.ts
new file mode 100644
index 0000000..32d360d
--- /dev/null
+++ b/packages/nativescript-intersection-observer/common.ts
@@ -0,0 +1,25 @@
+import { Observable, ScrollEventData, ScrollView, View } from '@nativescript/core';
+
+export abstract class IntersectionObserverCommon extends Observable {
+ view: View;
+ parentView: ScrollView;
+ callback: (isVisible: boolean) => void;
+ track(view: View, parentView: ScrollView, callback: (isVisible: boolean) => void) {
+ this.view = view;
+ this.parentView = parentView;
+ this.callback = callback;
+ parentView.on('scroll', this.onTrack.bind(this));
+ }
+
+ stopTrack() {
+ this.parentView.off('scroll', () => this.onTrack);
+ }
+
+ private onTrack(data: ScrollEventData) {
+ if (data.scrollY >= 0 && (data.object as View).getActualSize().height != 0) {
+ this.callback(this.isVisible(this.view, this.parentView));
+ }
+ }
+
+ abstract isVisible(view: View, parentView?: View): boolean;
+}
diff --git a/packages/nativescript-intersection-observer/index.android.ts b/packages/nativescript-intersection-observer/index.android.ts
new file mode 100644
index 0000000..af40c59
--- /dev/null
+++ b/packages/nativescript-intersection-observer/index.android.ts
@@ -0,0 +1,76 @@
+import { ScrollView, Utils, View } from '@nativescript/core';
+import { IntersectionObserverCommon } from './common';
+
+export class IntersectionObserver extends IntersectionObserverCommon {
+ displayMetrics: android.util.DisplayMetrics;
+
+ constructor() {
+ super();
+ this.displayMetrics = new android.util.DisplayMetrics();
+ Utils.android.getCurrentActivity().getWindowManager().getDefaultDisplay().getMetrics(this.displayMetrics);
+ }
+
+ isVisible(nsView: View, parentView?: ScrollView): boolean {
+ const view: android.view.View = nsView.android;
+ if (view == null) {
+ return false;
+ }
+ if (!view.isShown()) {
+ return false;
+ }
+
+ let actualPosition = new android.graphics.Rect();
+ view.getGlobalVisibleRect(actualPosition);
+ let screen = new android.graphics.Rect(0, 0, this.displayMetrics.widthPixels, this.displayMetrics.heightPixels);
+ return actualPosition.intersect(screen);
+ }
+}
+
+/* const scrollRef = ref()
+const hola = ref()
+
+
+useEventListener(scrollRef, {
+ scroll: (data) => {
+ if (data.scrollY > 0) {
+ if (data.object.getActualSize().height != 0)
+ console.log(isVisible(unrefView(hola)));
+ }
+ }
+})
+
+function isVisible(view: View) {
+ if (view) {
+ if (isAndroid) {
+ view = view.android
+ if (view == null) {
+ return false;
+ }
+ if (!view.isShown()) {
+ return false;
+ }
+ let displayMetrics = new android.util.DisplayMetrics();
+ Utils.android.getCurrentActivity().getWindowManager()
+ .getDefaultDisplay()
+ .getMetrics(displayMetrics);
+ let actualPosition = new android.graphics.Rect();
+ view.getGlobalVisibleRect(actualPosition);
+ let screen = new android.graphics.Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
+ return actualPosition.intersect(screen);
+ } else {
+ const myView = view.ios as UIView
+ const scrollView = unrefView(scrollRef).ios as UIScrollView
+
+ const thePosition = myView.frame;
+ const container = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, scrollView.frame.size.width, scrollView.frame.size.height)
+
+ if (CGRectIntersectsRect(thePosition, container)) {
+ console.log("HEREE HEREEHEREEHEREEHEREEHEREEHEREEHEREE");
+ return true
+ }
+
+ return false
+ }
+ }
+
+} */
diff --git a/packages/nativescript-intersection-observer/index.d.ts b/packages/nativescript-intersection-observer/index.d.ts
new file mode 100644
index 0000000..c180e50
--- /dev/null
+++ b/packages/nativescript-intersection-observer/index.d.ts
@@ -0,0 +1,8 @@
+import { View } from '@nativescript/core';
+import { IntersectionObserverCommon } from './common';
+
+export declare class IntersectionObserver extends IntersectionObserverCommon {
+ track(view: View, parentView: ScrollView, callback: (isVisible: boolean) => void): void;
+ stopTrack(): void;
+ isVisible(view: View, parentView?: ScrollView): boolean;
+}
diff --git a/packages/nativescript-intersection-observer/index.ios.ts b/packages/nativescript-intersection-observer/index.ios.ts
new file mode 100644
index 0000000..4a74c5d
--- /dev/null
+++ b/packages/nativescript-intersection-observer/index.ios.ts
@@ -0,0 +1,24 @@
+import { Screen, ScrollView, View } from '@nativescript/core';
+import { IntersectionObserverCommon } from './common';
+
+export class IntersectionObserver extends IntersectionObserverCommon {
+ topBarHeight = 0;
+
+ constructor() {
+ super();
+ this.topBarHeight = UIApplication?.sharedApplication?.statusBarFrame?.size?.height ?? 0;
+ }
+
+ isVisible(nsView: View, parentView?: ScrollView): boolean {
+ const view = nsView.ios as UIView;
+ const scrollView = parentView?.ios as UIScrollView;
+
+ const position = view?.frame;
+ if (position && scrollView) {
+ const container = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, scrollView.bounds.size.width, scrollView.bounds.size.height);
+ return container && CGRectIntersectsRect(position, container);
+ }
+
+ return false;
+ }
+}
diff --git a/packages/nativescript-intersection-observer/package.json b/packages/nativescript-intersection-observer/package.json
new file mode 100644
index 0000000..369e56f
--- /dev/null
+++ b/packages/nativescript-intersection-observer/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@nativescript-use/nativescript-intersection-observer",
+ "version": "0.0.2",
+ "description": "Add a plugin description",
+ "main": "index",
+ "typings": "index.d.ts",
+ "nativescript": {
+ "platforms": {
+ "ios": "6.0.0",
+ "android": "6.0.0"
+ }
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
+ },
+ "keywords": [
+ "NativeScript",
+ "JavaScript",
+ "TypeScript",
+ "iOS",
+ "Android"
+ ],
+ "author": {
+ "name": "Juan de Dios Martínez Vallejo",
+ "email": "oss@nativescript.org"
+ },
+ "bugs": {
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
+ },
+ "license": "Apache-2.0",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
+ "readmeFilename": "README.md",
+ "bootstrapper": "@nativescript/plugin-seed"
+}
diff --git a/packages/nativescript-intersection-observer/project.json b/packages/nativescript-intersection-observer/project.json
new file mode 100644
index 0000000..aa97506
--- /dev/null
+++ b/packages/nativescript-intersection-observer/project.json
@@ -0,0 +1,66 @@
+{
+ "name": "nativescript-intersection-observer",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "library",
+ "sourceRoot": "packages/nativescript-intersection-observer",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "options": {
+ "outputPath": "dist/packages/nativescript-intersection-observer",
+ "tsConfig": "packages/nativescript-intersection-observer/tsconfig.json",
+ "packageJson": "packages/nativescript-intersection-observer/package.json",
+ "main": "packages/nativescript-intersection-observer/index.d.ts",
+ "generatePackageJson": false,
+ "assets": [
+ "packages/nativescript-intersection-observer/*.md",
+ "packages/nativescript-intersection-observer/index.d.ts",
+ "LICENSE",
+ {
+ "glob": "**/*",
+ "input": "packages/nativescript-intersection-observer/platforms/",
+ "output": "./platforms/"
+ }
+ ],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ }
+ ]
+ }
+ },
+ "build.all": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["node tools/scripts/build-finish.ts nativescript-intersection-observer"],
+ "parallel": false
+ },
+ "outputs": ["dist/packages/nativescript-intersection-observer"],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ },
+ {
+ "target": "build",
+ "projects": "self"
+ }
+ ]
+ },
+ "focus": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-intersection-observer"],
+ "parallel": false
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": ["packages/nativescript-intersection-observer/**/*.ts"]
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/packages/nativescript-intersection-observer/references.d.ts b/packages/nativescript-intersection-observer/references.d.ts
new file mode 100644
index 0000000..22bac92
--- /dev/null
+++ b/packages/nativescript-intersection-observer/references.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/nativescript-intersection-observer/tsconfig.json b/packages/nativescript-intersection-observer/tsconfig.json
new file mode 100644
index 0000000..aed7323
--- /dev/null
+++ b/packages/nativescript-intersection-observer/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "rootDir": "."
+ },
+ "exclude": ["**/*.spec.ts", "**/*.test.ts", "angular"],
+ "include": ["**/*.ts", "references.d.ts"]
+}
diff --git a/packages/nativescript-keyboard/README.md b/packages/nativescript-keyboard/README.md
index 5265a22..c789bb3 100644
--- a/packages/nativescript-keyboard/README.md
+++ b/packages/nativescript-keyboard/README.md
@@ -1,13 +1,42 @@
-# @vallemar/nativescript-keyboard
+# @nativescript-use/nativescript-keyboard
```javascript
-npm install @vallemar/nativescript-keyboard
+npm install @nativescript-use/nativescript-keyboard
```
## Usage
-// TODO
+```ts
+import { Keyboard } from "@nativescript-use/nativescript-keyboard"
+
+const keyboard = new Keyboard();
+
+// Open keyboard with focus
+keyboard.keyboard(myView);
+
+// Close keyboard
+keyboard.close();
+
+// Add listener
+keyboard.onChangeVisibility((isOpen: boolean) =>{
+ console.log(isOpen)
+});
+// Remove listener
+keyboard.offChangeVisibility();
+```
+
+Type declaration
+```ts
+export declare class Keyboard {
+ onChangeVisibility(callback: (isOpen: boolean) => void): void
+ offChangeVisibility(): void
+ isOpen(): boolean
+ open(view: View): void
+ close(): void
+}
+```
## License
Apache License Version 2.0
+
diff --git a/packages/nativescript-keyboard/package.json b/packages/nativescript-keyboard/package.json
index 6a2fca5..762a407 100644
--- a/packages/nativescript-keyboard/package.json
+++ b/packages/nativescript-keyboard/package.json
@@ -1,6 +1,6 @@
{
- "name": "@vallemar/nativescript-keyboard",
- "version": "1.0.0",
+ "name": "@nativescript-use/nativescript-keyboard",
+ "version": "0.0.1",
"description": "Add a plugin description",
"main": "index",
"typings": "index.d.ts",
@@ -12,7 +12,7 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/NativeScript/plugins.git"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
},
"keywords": [
"NativeScript",
@@ -26,10 +26,10 @@
"email": "oss@nativescript.org"
},
"bugs": {
- "url": "https://github.com/NativeScript/plugins/issues"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
},
"license": "Apache-2.0",
- "homepage": "https://github.com/NativeScript/plugins",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
"readmeFilename": "README.md",
"bootstrapper": "@nativescript/plugin-seed"
}
diff --git a/packages/nativescript-keyboard/project.json b/packages/nativescript-keyboard/project.json
index 40baaed..7c2158e 100644
--- a/packages/nativescript-keyboard/project.json
+++ b/packages/nativescript-keyboard/project.json
@@ -5,12 +5,13 @@
"sourceRoot": "packages/nativescript-keyboard",
"targets": {
"build": {
- "executor": "@nrwl/js:tsc",
+ "executor": "@nx/js:tsc",
"options": {
"outputPath": "dist/packages/nativescript-keyboard",
"tsConfig": "packages/nativescript-keyboard/tsconfig.json",
"packageJson": "packages/nativescript-keyboard/package.json",
"main": "packages/nativescript-keyboard/index.d.ts",
+ "generatePackageJson": false,
"assets": [
"packages/nativescript-keyboard/*.md",
"packages/nativescript-keyboard/index.d.ts",
@@ -32,14 +33,10 @@
"build.all": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "node tools/scripts/build-finish.ts nativescript-keyboard"
- ],
+ "commands": ["node tools/scripts/build-finish.ts nativescript-keyboard"],
"parallel": false
},
- "outputs": [
- "dist/packages/nativescript-keyboard"
- ],
+ "outputs": ["dist/packages/nativescript-keyboard"],
"dependsOn": [
{
"target": "build.all",
@@ -54,18 +51,14 @@
"focus": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "nx g @nativescript/plugin-tools:focus-packages nativescript-keyboard"
- ],
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-keyboard"],
"parallel": false
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
- "lintFilePatterns": [
- "packages/nativescript-keyboard/**/*.ts"
- ]
+ "lintFilePatterns": ["packages/nativescript-keyboard/**/*.ts"]
}
}
},
diff --git a/packages/nativescript-localstorage/.eslintrc.json b/packages/nativescript-localstorage/.eslintrc.json
new file mode 100644
index 0000000..53c06c8
--- /dev/null
+++ b/packages/nativescript-localstorage/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*", "node_modules/**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/packages/nativescript-localstorage/README.md b/packages/nativescript-localstorage/README.md
new file mode 100644
index 0000000..5426102
--- /dev/null
+++ b/packages/nativescript-localstorage/README.md
@@ -0,0 +1,68 @@
+# @nativescript-use/nativescript-localstorage
+
+```javascript
+npm install @nativescript-use/nativescript-localstorage
+```
+
+Use localStorage like in the browser.
+This library uses [ApplicationSettings](https://docs.nativescript.org/core/application-settings) from NativeScript behind it.
+
+## Usage
+```ts
+import localStorage from '@nativescript-use/nativescript-localstorage';
+
+localStorage.setItem('myKey', "myValue");
+localStorage.getItem('myKey'); // -> "myValue"
+localStorage.has('myKey');
+localStorage.removeItem('myKey');
+localStorage.length();
+localStorage.clear();
+```
+
+## Extend LocalStorage class
+
+You can define a storage with a prefix for all entries in ApplicationSettings like:
+
+```ts
+// BusinessStorage.ts
+import { LocalStorage } from '@nativescript-use/nativescript-localstorage';
+
+export enum BusinessKeys {
+ NAME = 'name',
+}
+
+class BusinessStorage extends LocalStorage {
+ prefix = '_businnes_.';
+}
+const businessStorage = new BusinessStorage();
+export default businessStorage;
+```
+
+And use it like.
+```ts
+import businessStorage, { BusinessKeys } from './BusinessStorage';
+
+businessStorage.setItem(BusinessKeys.NAME, 'MyBusiness');
+businessStorage.getItem(BusinessKeys.NAME);
+
+```
+This will generate the following entry in ApplicationSettings
+```
+_businnes_.name = 'MyBusiness'
+```
+## Type declaration
+```ts
+declare class LocalStorage {
+ protected prefix: string;
+ getItem(key: K): T;
+ setItem(key: K, data: any): void;
+ has(key: K): boolean;
+ removeItem(key: K): void;
+ length(): number;
+ clear(): void;
+}
+export declare const localStorage: LocalStorage;
+```
+## License
+
+Apache License Version 2.0
diff --git a/packages/nativescript-localstorage/index.ts b/packages/nativescript-localstorage/index.ts
new file mode 100644
index 0000000..8248ab0
--- /dev/null
+++ b/packages/nativescript-localstorage/index.ts
@@ -0,0 +1,47 @@
+import { ApplicationSettings } from '@nativescript/core';
+
+export class LocalStorage {
+ protected prefix = '';
+
+ getItem(key: K): T {
+ try {
+ return ApplicationSettings.getString(this.getKey(key)) as T;
+ } catch (error) {
+ console.log('[LOCAL_STORAGE] getItem ERROR ' + error);
+ }
+ return null;
+ }
+
+ setItem(key: K, data: any): void {
+ try {
+ ApplicationSettings.setString(this.getKey(key), isString(data) ? data : JSON.stringify(data));
+ } catch (error) {
+ console.log('[LOCAL_STORAGE] setItem ERROR ' + error);
+ }
+ }
+
+ has(key: K): boolean {
+ return ApplicationSettings.hasKey(this.getKey(key));
+ }
+
+ removeItem(key: K): void {
+ ApplicationSettings.remove(this.getKey(key));
+ }
+
+ length(): number {
+ return ApplicationSettings.getAllKeys().length;
+ }
+
+ clear(): void {
+ ApplicationSettings.clear();
+ }
+
+ private getKey(key: K) {
+ return this.prefix + key;
+ }
+}
+
+const localStorage = new LocalStorage();
+export default localStorage;
+
+const isString = (val: unknown): val is string => typeof val === 'string';
diff --git a/packages/nativescript-localstorage/package.json b/packages/nativescript-localstorage/package.json
new file mode 100644
index 0000000..1f2cb19
--- /dev/null
+++ b/packages/nativescript-localstorage/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@nativescript-use/nativescript-localstorage",
+ "version": "0.0.1",
+ "description": "Add a plugin description",
+ "main": "index",
+ "typings": "index.d.ts",
+ "nativescript": {
+ "platforms": {
+ "ios": "6.0.0",
+ "android": "6.0.0"
+ }
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
+ },
+ "keywords": [
+ "NativeScript",
+ "JavaScript",
+ "TypeScript",
+ "iOS",
+ "Android"
+ ],
+ "author": {
+ "name": "Juan de Dios Martínez Vallejo",
+ "email": "oss@nativescript.org"
+ },
+ "bugs": {
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
+ },
+ "license": "Apache-2.0",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
+ "readmeFilename": "README.md",
+ "bootstrapper": "@nativescript/plugin-seed"
+}
diff --git a/packages/nativescript-localstorage/project.json b/packages/nativescript-localstorage/project.json
new file mode 100644
index 0000000..7ca149b
--- /dev/null
+++ b/packages/nativescript-localstorage/project.json
@@ -0,0 +1,66 @@
+{
+ "name": "nativescript-localstorage",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "library",
+ "sourceRoot": "packages/nativescript-localstorage",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "options": {
+ "outputPath": "dist/packages/nativescript-localstorage",
+ "tsConfig": "packages/nativescript-localstorage/tsconfig.json",
+ "packageJson": "packages/nativescript-localstorage/package.json",
+ "main": "packages/nativescript-localstorage/index.d.ts",
+ "generatePackageJson": false,
+ "assets": [
+ "packages/nativescript-localstorage/*.md",
+ "packages/nativescript-localstorage/index.d.ts",
+ "LICENSE",
+ {
+ "glob": "**/*",
+ "input": "packages/nativescript-localstorage/platforms/",
+ "output": "./platforms/"
+ }
+ ],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ }
+ ]
+ }
+ },
+ "build.all": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["node tools/scripts/build-finish.ts nativescript-localstorage"],
+ "parallel": false
+ },
+ "outputs": ["dist/packages/nativescript-localstorage"],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ },
+ {
+ "target": "build",
+ "projects": "self"
+ }
+ ]
+ },
+ "focus": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-localstorage"],
+ "parallel": false
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": ["packages/nativescript-localstorage/**/*.ts"]
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/packages/nativescript-localstorage/references.d.ts b/packages/nativescript-localstorage/references.d.ts
new file mode 100644
index 0000000..22bac92
--- /dev/null
+++ b/packages/nativescript-localstorage/references.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/nativescript-localstorage/tsconfig.json b/packages/nativescript-localstorage/tsconfig.json
new file mode 100644
index 0000000..aed7323
--- /dev/null
+++ b/packages/nativescript-localstorage/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "rootDir": "."
+ },
+ "exclude": ["**/*.spec.ts", "**/*.test.ts", "angular"],
+ "include": ["**/*.ts", "references.d.ts"]
+}
diff --git a/packages/nativescript-media-query/.eslintrc.json b/packages/nativescript-media-query/.eslintrc.json
new file mode 100644
index 0000000..53c06c8
--- /dev/null
+++ b/packages/nativescript-media-query/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*", "node_modules/**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/packages/nativescript-media-query/README.md b/packages/nativescript-media-query/README.md
new file mode 100644
index 0000000..1dd009b
--- /dev/null
+++ b/packages/nativescript-media-query/README.md
@@ -0,0 +1,64 @@
+# DEPRECATED. NativeScript introduced media queries in version 8.8. We've deprecated this package in favor of using @nativescript/core. Official documentation is available [here](https://docs.nativescript.org/guide/styling#media-queries-8-8).
+
+
+# @nativescript-use/nativescript-media-query
+
+```javascript
+npm install @nativescript-use/nativescript-media-query
+```
+
+## Usage
+
+```ts
+import { matchMedia, MediaQueryList } from "@nativescript-use/nativescript-media-query"
+
+const mql: MediaQueryList = matchMedia("(min-width: 400)");
+
+if (mql.matches) {
+ /* The screen is at least 400 dpi wide */
+} else {
+ /* The screen is less than 400 dpi wide */
+}
+
+
+// Add listener
+mql.onchange = (event: MediaQueryListEvent) => {
+ // some logic
+});
+
+const myListener = () => console.log("Change!");
+
+mql.addListener(myListener);
+
+// Remove listener
+mql.removeListener(myListener);
+
+```
+
+Type declaration
+```ts
+export interface MediaQueryList {
+ readonly matches: boolean;
+ readonly media: string;
+ onchange: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
+ addListener(listener: MediaQueryListListener): void;
+ removeListener(listener: MediaQueryListListener): void;
+}
+
+export type MediaQueryListListener = (mql: MediaQueryList) => void;
+
+export interface MediaQueryListEvent {
+ readonly matches: boolean;
+ readonly media: string;
+}
+
+export declare function matchMedia(mediaQueryString: string): MediaQueryList;
+
+```
+
+## License
+
+Apache License Version 2.0
+
+
+
diff --git a/packages/nativescript-media-query/index.d.ts b/packages/nativescript-media-query/index.d.ts
new file mode 100644
index 0000000..ef1a7fb
--- /dev/null
+++ b/packages/nativescript-media-query/index.d.ts
@@ -0,0 +1,16 @@
+export declare interface MediaQueryList {
+ readonly matches: boolean;
+ readonly media: string;
+ onchange: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
+ addListener(listener: MediaQueryListListener): void;
+ removeListener(listener: MediaQueryListListener): void;
+}
+
+export declare type MediaQueryListListener = (mql: MediaQueryList) => void;
+
+export declare interface MediaQueryListEvent {
+ readonly matches: boolean;
+ readonly media: string;
+}
+
+export declare function matchMedia(mediaQueryString: string): MediaQueryList;
diff --git a/packages/nativescript-media-query/index.ts b/packages/nativescript-media-query/index.ts
new file mode 100644
index 0000000..c8c7878
--- /dev/null
+++ b/packages/nativescript-media-query/index.ts
@@ -0,0 +1,155 @@
+import { Screen, Application } from '@nativescript/core';
+
+/**
+ * @deprecated. NativeScript introduced media queries in version 8.8. We've deprecated this package in favor of using @nativescript/core. Official documentation is available [here](https://docs.nativescript.org/guide/styling#media-queries-8-8)
+ */
+export interface MediaQueryList {
+ readonly matches: boolean;
+ readonly media: string;
+ onchange: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
+ addListener(listener: MediaQueryListListener): void;
+ removeListener(listener: MediaQueryListListener): void;
+}
+
+/**
+ * @deprecated. NativeScript introduced media queries in version 8.8. We've deprecated this package in favor of using @nativescript/core. Official documentation is available [here](https://docs.nativescript.org/guide/styling#media-queries-8-8)
+ */
+export type MediaQueryListListener = (mql: MediaQueryList) => void;
+
+/**
+ * @deprecated. NativeScript introduced media queries in version 8.8. We've deprecated this package in favor of using @nativescript/core. Official documentation is available [here](https://docs.nativescript.org/guide/styling#media-queries-8-8)
+ */
+export interface MediaQueryListEvent {
+ readonly matches: boolean;
+ readonly media: string;
+}
+
+/**
+ * @deprecated. NativeScript introduced media queries in version 8.8. We've deprecated this package in favor of using @nativescript/core. Official documentation is available [here](https://docs.nativescript.org/guide/styling#media-queries-8-8)
+ */
+export const matchMedia = (mediaQueryString: string) => {
+ const factory = MediaQueryListFactory.getInstance();
+ const mql = factory.create(mediaQueryString);
+
+ factory.updateMatches();
+ return mql;
+};
+
+class MediaQueryListImpl implements MediaQueryList {
+ private listeners: Set = new Set();
+ public matches: boolean = false;
+
+ constructor(public media: string) {}
+
+ public onchange: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null = null;
+
+ public addListener(listener: MediaQueryListListener): void {
+ this.listeners.add(listener);
+ }
+
+ public removeListener(listener: MediaQueryListListener): void {
+ this.listeners.delete(listener);
+ }
+
+ public dispatchChangeEvent(): void {
+ const event: MediaQueryListEvent = {
+ matches: this.matches,
+ media: this.media,
+ };
+
+ for (const listener of this.listeners) {
+ listener(this);
+ }
+
+ if (typeof this.onchange === 'function') {
+ this.onchange.call(this, event);
+ }
+ }
+
+ public updateMatches(matches: boolean): void {
+ if (this.matches !== matches) {
+ this.matches = matches;
+ this.dispatchChangeEvent();
+ }
+ }
+}
+
+class MediaQueryListFactory {
+ private static instance: MediaQueryListFactory;
+ private lists: MediaQueryListImpl[] = [];
+
+ private constructor() {}
+
+ public static getInstance(): MediaQueryListFactory {
+ if (!MediaQueryListFactory.instance) {
+ MediaQueryListFactory.instance = new MediaQueryListFactory();
+ // Condition for update
+ Application.on('orientationChanged', () => {
+ setTimeout(() => {
+ MediaQueryListFactory.instance.updateMatches();
+ }, 10);
+ });
+ }
+ return MediaQueryListFactory.instance;
+ }
+
+ public create(media: string): MediaQueryListImpl {
+ const mql = new MediaQueryListImpl(media);
+ this.lists.push(mql);
+ return mql;
+ }
+
+ public remove(mql: MediaQueryListImpl): void {
+ const index = this.lists.indexOf(mql);
+ if (index > -1) {
+ this.lists.splice(index, 1);
+ }
+ }
+
+ public updateMatches(): void {
+ for (const mql of this.lists) {
+ const queryParts = this.extractQueryParts(mql.media);
+ const matches = this.checkMediaQuery(queryParts);
+ mql.updateMatches(matches);
+ }
+ }
+
+ private extractQueryParts(mediaQuery: string): string[] {
+ const query = mediaQuery.trim().slice(1, -1);
+ const parts = query.split(' and ');
+ return parts.map((part) => part.replace('(', '').replace(')', '').trim());
+ }
+
+ private checkMediaQuery(queryParts: string[]): boolean {
+ return queryParts.map((part) => evaluatePart(part)).every(Boolean);
+ }
+}
+
+function evaluatePart(part: string): boolean {
+ const [property, value] = part.split(':');
+ const trimmedProperty = property.trim();
+ const trimmedValue = value.trim();
+ if (trimmedProperty.includes('width') || trimmedProperty.includes('height')) {
+ const realWidth = Screen.mainScreen.widthDIPs;
+ const realHeight = Screen.mainScreen.heightDIPs;
+
+ if (trimmedProperty === 'width') {
+ return parseInt(realWidth.toString(), 10) === parseInt(trimmedValue, 10);
+ } else if (trimmedProperty === 'min-width') {
+ return realWidth >= parseInt(trimmedValue, 10);
+ } else if (trimmedProperty === 'max-width') {
+ return realWidth <= parseInt(trimmedValue, 10);
+ } else if (trimmedProperty === 'height') {
+ return parseInt(realHeight.toString(), 10) === parseInt(trimmedValue, 10);
+ } else if (trimmedProperty === 'min-height') {
+ return realHeight >= parseInt(trimmedValue, 10);
+ } else if (trimmedProperty === 'max-height') {
+ return realHeight <= parseInt(trimmedValue, 10);
+ }
+ } else if (trimmedProperty === 'orientation') {
+ return Application.orientation() === trimmedValue;
+ } else {
+ // TBD
+ return false;
+ }
+}
diff --git a/packages/nativescript-media-query/package.json b/packages/nativescript-media-query/package.json
new file mode 100644
index 0000000..9a73832
--- /dev/null
+++ b/packages/nativescript-media-query/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@nativescript-use/nativescript-media-query",
+ "version": "0.0.5",
+ "description": "Add a plugin description",
+ "main": "index",
+ "typings": "index.d.ts",
+ "nativescript": {
+ "platforms": {
+ "ios": "6.0.0",
+ "android": "6.0.0"
+ }
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
+ },
+ "keywords": [
+ "NativeScript",
+ "JavaScript",
+ "TypeScript",
+ "iOS",
+ "Android"
+ ],
+ "author": {
+ "name": "Juan de Dios Martínez Vallejo",
+ "email": "oss@nativescript.org"
+ },
+ "bugs": {
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
+ },
+ "license": "Apache-2.0",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
+ "readmeFilename": "README.md",
+ "bootstrapper": "@nativescript/plugin-seed"
+}
diff --git a/packages/nativescript-media-query/project.json b/packages/nativescript-media-query/project.json
new file mode 100644
index 0000000..b4d9527
--- /dev/null
+++ b/packages/nativescript-media-query/project.json
@@ -0,0 +1,66 @@
+{
+ "name": "nativescript-media-query",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "library",
+ "sourceRoot": "packages/nativescript-media-query",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "options": {
+ "outputPath": "dist/packages/nativescript-media-query",
+ "tsConfig": "packages/nativescript-media-query/tsconfig.json",
+ "packageJson": "packages/nativescript-media-query/package.json",
+ "main": "packages/nativescript-media-query/index.d.ts",
+ "generatePackageJson": false,
+ "assets": [
+ "packages/nativescript-media-query/*.md",
+ "packages/nativescript-media-query/index.d.ts",
+ "LICENSE",
+ {
+ "glob": "**/*",
+ "input": "packages/nativescript-media-query/platforms/",
+ "output": "./platforms/"
+ }
+ ],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ }
+ ]
+ }
+ },
+ "build.all": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["node tools/scripts/build-finish.ts nativescript-media-query"],
+ "parallel": false
+ },
+ "outputs": ["dist/packages/nativescript-media-query"],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ },
+ {
+ "target": "build",
+ "projects": "self"
+ }
+ ]
+ },
+ "focus": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-media-query"],
+ "parallel": false
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": ["packages/nativescript-media-query/**/*.ts"]
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/packages/nativescript-media-query/references.d.ts b/packages/nativescript-media-query/references.d.ts
new file mode 100644
index 0000000..22bac92
--- /dev/null
+++ b/packages/nativescript-media-query/references.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/nativescript-media-query/tsconfig.json b/packages/nativescript-media-query/tsconfig.json
new file mode 100644
index 0000000..aed7323
--- /dev/null
+++ b/packages/nativescript-media-query/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "rootDir": "."
+ },
+ "exclude": ["**/*.spec.ts", "**/*.test.ts", "angular"],
+ "include": ["**/*.ts", "references.d.ts"]
+}
diff --git a/packages/nativescript-orientation/README.md b/packages/nativescript-orientation/README.md
index 7429bb7..09c8e69 100644
--- a/packages/nativescript-orientation/README.md
+++ b/packages/nativescript-orientation/README.md
@@ -1,13 +1,50 @@
-# @vallemar/nativescript-orientation
+# @nativescript-use/nativescript-orientation
```javascript
-npm install @vallemar/nativescript-orientation
+npm install @nativescript-use/nativescript-orientation
```
## Usage
-// TODO
+```ts
+import { Orientation } from "@nativescript-use/nativescript-orientation"
+
+const orientation = new Orientation();
+
+// Get current orientation
+const currentOrientation = orientation.getOrientation();
+
+// Change orientation. values: 'landscape' | 'landscaperight' | 'landscapeleft' | 'portrait'
+orientation.setOrientation('landscape');
+
+// Enable rotation
+orientation.enableRotation();
+
+// Disable rotation
+orientation.disableRotation();
+
+// Add listener
+orientation.onChangedOrientation((newValue: CoreTypes.DeviceOrientationType) =>{
+ console.log(newValue)
+});
+// Remove listener
+orientation.offChangedOrientation();
+```
+
+Type declaration
+```ts
+export declare class Orientation {
+ getOrientation(): CoreTypes.DeviceOrientationType
+ onChangedOrientation(callback: (newValue: CoreTypes.DeviceOrientationType) => void): void
+ offChangedOrientation(): void
+ enableRotation(): void
+ disableRotation(): void
+ setOrientation(value: 'landscape' | 'landscaperight' | 'landscapeleft' | 'portrait', animation: false): void
+}
+```
## License
Apache License Version 2.0
+
+
diff --git a/packages/nativescript-orientation/index.android.ts b/packages/nativescript-orientation/index.android.ts
index 63166c6..12e9581 100644
--- a/packages/nativescript-orientation/index.android.ts
+++ b/packages/nativescript-orientation/index.android.ts
@@ -1,69 +1,62 @@
-import { CoreTypes, Utils } from "@nativescript/core";
-import { OrientationBase } from "./common";
-
+import { CoreTypes, Utils } from '@nativescript/core';
+import { OrientationBase } from './common';
export class Orientation extends OrientationBase {
- getOrientation(): CoreTypes.DeviceOrientationType {
- const orientation = Utils.android.getApplicationContext().getResources().getConfiguration().orientation;
- if (orientation === android.content.res.Configuration.ORIENTATION_LANDSCAPE) {
- return CoreTypes.DeviceOrientation.landscape;
- } else if (orientation === android.content.res.Configuration.ORIENTATION_PORTRAIT) {
- return CoreTypes.DeviceOrientation.portrait;
- }
- return CoreTypes.DeviceOrientation.unknown;
- }
-
- enableRotation(): void {
- Utils.android.getCurrentActivity().setRequestedOrientation(13);
+ getOrientation(): CoreTypes.DeviceOrientationType {
+ const orientation = Utils.android.getApplicationContext().getResources().getConfiguration().orientation;
+ if (orientation === android.content.res.Configuration.ORIENTATION_LANDSCAPE) {
+ return CoreTypes.DeviceOrientation.landscape;
+ } else if (orientation === android.content.res.Configuration.ORIENTATION_PORTRAIT) {
+ return CoreTypes.DeviceOrientation.portrait;
}
-
- disableRotation(): void {
- Utils.android.getCurrentActivity().setRequestedOrientation(14);
- }
-
- setOrientation(value: "portrait" | "landscape" | "landscaperight" | "landscapeleft", animation: false): void {
- var val = value.toLowerCase();
- var newOrientation;
- switch (val) {
- case 'landscape':
- newOrientation = 6; // SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6
- break;
-
- case 'landscaperight':
- newOrientation = 0; // SCREEN_ORIENTATION_LANDSCAPE = 0
- break;
-
- case 'landscapeleft':
- newOrientation = 8; // SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 9
- break;
-
- case 'portrait':
- default:
- newOrientation = 1; // SCREEN_ORIENTATION_PORTRAIT = 1
- break;
- }
- Utils.android.getCurrentActivity().setRequestedOrientation(newOrientation);
+ return CoreTypes.DeviceOrientation.unknown;
+ }
+
+ enableRotation(): void {
+ Utils.android.getCurrentActivity().setRequestedOrientation(13);
+ }
+
+ disableRotation(): void {
+ Utils.android.getCurrentActivity().setRequestedOrientation(14);
+ }
+
+ setOrientation(value: 'portrait' | 'landscape' | 'landscaperight' | 'landscapeleft', animation = false): void {
+ var val = value.toLowerCase();
+ var newOrientation;
+ switch (val) {
+ case 'landscape':
+ newOrientation = 6; // SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6
+ break;
+
+ case 'landscaperight':
+ newOrientation = 0; // SCREEN_ORIENTATION_LANDSCAPE = 0
+ break;
+
+ case 'landscapeleft':
+ newOrientation = 8; // SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 9
+ break;
+
+ case 'portrait':
+ default:
+ newOrientation = 1; // SCREEN_ORIENTATION_PORTRAIT = 1
+ break;
}
-
- setFullScreen(fullScreen: boolean): void {
- var View = android.view.View;
- var WindowManager = android.view.WindowManager;
- var window = Utils.android.getCurrentActivity().getWindow();
-
- fullScreen = !!fullScreen;
-
- if (fullScreen) {
- window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- } else {
- window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
+ Utils.android.getCurrentActivity().setRequestedOrientation(newOrientation);
+ }
+
+ setFullScreen(fullScreen: boolean): void {
+ var View = android.view.View;
+ var WindowManager = android.view.WindowManager;
+ var window = Utils.android.getCurrentActivity().getWindow();
+
+ fullScreen = !!fullScreen;
+
+ if (fullScreen) {
+ window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ } else {
+ window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
-
-}
\ No newline at end of file
+ }
+}
diff --git a/packages/nativescript-orientation/index.d.ts b/packages/nativescript-orientation/index.d.ts
index 165adae..036689d 100644
--- a/packages/nativescript-orientation/index.d.ts
+++ b/packages/nativescript-orientation/index.d.ts
@@ -1,11 +1,9 @@
-
export declare class Orientation {
- getOrientation(): CoreTypes.DeviceOrientationType
- onChangedOrientation(callback: (newValue: CoreTypes.DeviceOrientationType) => void): void
- offChangedOrientation(): void
- enableRotation(): void
- disableRotation(): void
- setOrientation(value: 'landscape' | 'landscaperight' | 'landscapeleft' | 'portrait', animation: false): void
- setFullScreen(fullScreen: boolean): void
-
-}
\ No newline at end of file
+ getOrientation(): CoreTypes.DeviceOrientationType;
+ onChangedOrientation(callback: (newValue: CoreTypes.DeviceOrientationType) => void): void;
+ offChangedOrientation(): void;
+ enableRotation(): void;
+ disableRotation(): void;
+ setOrientation(value: 'landscape' | 'landscaperight' | 'landscapeleft' | 'portrait', animation = false): void;
+ setFullScreen(fullScreen: boolean): void;
+}
diff --git a/packages/nativescript-orientation/index.ios.ts b/packages/nativescript-orientation/index.ios.ts
index 7c51bb9..a122c1f 100644
--- a/packages/nativescript-orientation/index.ios.ts
+++ b/packages/nativescript-orientation/index.ios.ts
@@ -1,155 +1,159 @@
-import { CoreTypes, Device, Frame } from "@nativescript/core";
-import { OrientationBase } from "./common";
-
+import { CoreTypes, Device, Frame } from '@nativescript/core';
+import { OrientationBase } from './common';
export class Orientation extends OrientationBase {
- protected interfaceOrientationMask: any;
- protected lockRotation = false;
-
- getOrientation(): CoreTypes.DeviceOrientationType {
- var device = UIDevice.currentDevice;
-
- switch (device.orientation) {
- case UIDeviceOrientation.LandscapeLeft:
- case UIDeviceOrientation.LandscapeRight:
- return CoreTypes.DeviceOrientation.landscape;
- case UIDeviceOrientation.Portrait:
- case UIDeviceOrientation.PortraitUpsideDown:
- return CoreTypes.DeviceOrientation.portrait;
- default:
-
- let orientation: any = undefined;
- if (parseFloat(Device.osVersion) >= 13) {
- orientation = UIApplication.sharedApplication?.windows?.firstObject?.windowScene?.interfaceOrientation ?? CoreTypes.DeviceOrientation.unknown
- } else {
- orientation = UIApplication.sharedApplication?.statusBarOrientation ?? CoreTypes.DeviceOrientation.unknown;
- }
- if (orientation === 1 || orientation === 2) { return CoreTypes.DeviceOrientation.portrait; }
- else if (orientation && orientation !== CoreTypes.DeviceOrientation.unknown) { return CoreTypes.DeviceOrientation.landscape; }
-
- }
- return CoreTypes.DeviceOrientation.unknown;
- }
-
- enableRotation(): void {
- this.interfaceOrientationMask = UIInterfaceOrientationMask.All;
- this.lockRotation = false;
- this.updateiOSLockScreen();
- }
-
- disableRotation(): void {
- this.interfaceOrientationMask = this.getMakFormInterfaceOrientation();
- this.lockRotation = true;
- this.updateiOSLockScreen();
- }
-
- setOrientation(value: "portrait" | "landscape" | "landscaperight" | "landscapeleft", animation: false): void {
- if (parseFloat(Device.osVersion) >= 16) {
- var newOrientation, val = value.toLowerCase();
- if (val === 'landscape' || val === 'landscaperight') {
- newOrientation = UIInterfaceOrientationMask.LandscapeRight;
- } else if (val === 'landscapeleft') {
- newOrientation = UIInterfaceOrientationMask.LandscapeLeft;
- } else {
- newOrientation = UIInterfaceOrientationMask.Portrait;
- }
-
- UINavigationController.attemptRotationToDeviceOrientation();
- const orientation = UIWindowSceneGeometryPreferencesIOS.alloc()
- .initWithInterfaceOrientations(newOrientation)
- let windowScene: UIWindowScene = UIApplication.sharedApplication.connectedScenes.allObjects[0] as UIWindowScene
- windowScene?.requestGeometryUpdateWithPreferencesErrorHandler(orientation,
- (e) => {
- console.log(e);
- })
+ protected interfaceOrientationMask: any;
+ protected lockRotation = false;
+
+ getOrientation(): CoreTypes.DeviceOrientationType {
+ var device = UIDevice.currentDevice;
+
+ switch (device.orientation) {
+ case UIDeviceOrientation.LandscapeLeft:
+ case UIDeviceOrientation.LandscapeRight:
+ return CoreTypes.DeviceOrientation.landscape;
+ case UIDeviceOrientation.Portrait:
+ case UIDeviceOrientation.PortraitUpsideDown:
+ return CoreTypes.DeviceOrientation.portrait;
+ default:
+ let orientation: any = undefined;
+ if (parseFloat(Device.osVersion) >= 13) {
+ orientation = UIApplication.sharedApplication?.windows?.firstObject?.windowScene?.interfaceOrientation ?? CoreTypes.DeviceOrientation.unknown;
} else {
- var newOrientation, val = value.toLowerCase();
- if (val === 'landscape' || val === 'landscaperight') {
- newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.LandscapeRight);
- } else if (val === 'landscapeleft') {
- newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.LandscapeLeft);
- } else {
- newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.Portrait);
- }
- var device = UIDevice.currentDevice;
- if (animation === false) {
- UIView.setAnimationsEnabled(false);
- }
-
- var currentOrientation = device.orientation;
- // We have to swap to a different orientation FIRST, if the current orientation matches
- if (newOrientation === currentOrientation) {
- var tempOrientation = newOrientation - 1;
- if (tempOrientation < 1) { tempOrientation += 2; }
- device.setValueForKey(tempOrientation, "orientation");
- }
-
- device.setValueForKey(newOrientation, "orientation");
-
- if (animation === false) {
- UIView.setAnimationsEnabled(true);
- }
+ orientation = UIApplication.sharedApplication?.statusBarOrientation ?? CoreTypes.DeviceOrientation.unknown;
+ }
+ if (orientation === 1 || orientation === 2) {
+ return CoreTypes.DeviceOrientation.portrait;
+ } else if (orientation && orientation !== CoreTypes.DeviceOrientation.unknown) {
+ return CoreTypes.DeviceOrientation.landscape;
}
}
-
- setFullScreen(fullScreen: boolean): void {
- throw new Error("Method not implemented.");
- }
-
- private updateiOSLockScreen() {
-
- UINavigationController.attemptRotationToDeviceOrientation();
- var app: UIViewController = Frame.topmost().ios.controller;
- var shouldAutorotate = this.findRootPrototype(app, "shouldAutorotate");
- var shouldAutorotateToInterfaceOrientation = this.findRootPrototype(app, "shouldAutorotateToInterfaceOrientation");
-
- Object.defineProperty(shouldAutorotate, "shouldAutorotate", {
- get: function () {
- //console.log("shouldAutorotate rotate");
- return !this.lockRotation;
- }, enumerable: true, configurable: true
- });
-
- Object.defineProperty(shouldAutorotateToInterfaceOrientation, "shouldAutorotateToInterfaceOrientation", {
- get: function () {
- //console.log("shouldAutorotateToInterfaceOrientation rotate");
- return !this.lockRotation;
- }, enumerable: true, configurable: true
- });
- if (parseFloat(Device.osVersion) >= 16) {
- var supportedInterfaceOrientations = this.findRootPrototype(app, "supportedInterfaceOrientations");
-
- Object.defineProperty(supportedInterfaceOrientations, "supportedInterfaceOrientations", {
- get: function () {
- //console.log("supportedInterfaceOrientations rotate " + orientationCore.interfaceOrientationMask);
- return this.interfaceOrientationMask;
- }, enumerable: true, configurable: true
- });
+ return CoreTypes.DeviceOrientation.unknown;
+ }
+
+ enableRotation(): void {
+ this.interfaceOrientationMask = UIInterfaceOrientationMask.All;
+ this.lockRotation = false;
+ this.updateiOSLockScreen();
+ }
+
+ disableRotation(): void {
+ this.interfaceOrientationMask = this.getMakFormInterfaceOrientation();
+ this.lockRotation = true;
+ this.updateiOSLockScreen();
+ }
+
+ setOrientation(value: 'portrait' | 'landscape' | 'landscaperight' | 'landscapeleft', animation = false): void {
+ if (parseFloat(Device.osVersion) >= 16) {
+ var newOrientation,
+ val = value.toLowerCase();
+ if (val === 'landscape' || val === 'landscaperight') {
+ newOrientation = UIInterfaceOrientationMask.LandscapeRight;
+ } else if (val === 'landscapeleft') {
+ newOrientation = UIInterfaceOrientationMask.LandscapeLeft;
+ } else {
+ newOrientation = UIInterfaceOrientationMask.Portrait;
+ }
+
+ UINavigationController.attemptRotationToDeviceOrientation();
+ const orientation = UIWindowSceneGeometryPreferencesIOS.alloc().initWithInterfaceOrientations(newOrientation);
+ let windowScene: UIWindowScene = UIApplication.sharedApplication.connectedScenes.allObjects[0] as UIWindowScene;
+ windowScene?.requestGeometryUpdateWithPreferencesErrorHandler(orientation, (e) => {
+ console.log(e);
+ });
+ } else {
+ var newOrientation,
+ val = value.toLowerCase();
+ if (val === 'landscape' || val === 'landscaperight') {
+ newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.LandscapeRight);
+ } else if (val === 'landscapeleft') {
+ newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.LandscapeLeft);
+ } else {
+ newOrientation = NSNumber.numberWithInt(UIDeviceOrientation.Portrait);
+ }
+ var device = UIDevice.currentDevice;
+ if (animation === false) {
+ UIView.setAnimationsEnabled(false);
+ }
+
+ var currentOrientation = device.orientation;
+ // We have to swap to a different orientation FIRST, if the current orientation matches
+ if (newOrientation === currentOrientation) {
+ var tempOrientation = newOrientation - 1;
+ if (tempOrientation < 1) {
+ tempOrientation += 2;
}
+ device.setValueForKey(tempOrientation, 'orientation');
+ }
- }
+ device.setValueForKey(newOrientation, 'orientation');
- private getMakFormInterfaceOrientation() {
- const orientation = UIApplication.sharedApplication?.windows?.firstObject?.windowScene?.interfaceOrientation;
- switch (orientation) {
- case UIInterfaceOrientation.LandscapeLeft:
- return UIInterfaceOrientationMask.LandscapeLeft
- case UIInterfaceOrientation.LandscapeRight:
- return UIInterfaceOrientationMask.LandscapeRight
- case UIInterfaceOrientation.Portrait:
- return UIInterfaceOrientationMask.Portrait
- case UIInterfaceOrientation.PortraitUpsideDown:
- return UIInterfaceOrientationMask.PortraitUpsideDown
- default:
- return UIInterfaceOrientationMask.Portrait
- }
+ if (animation === false) {
+ UIView.setAnimationsEnabled(true);
+ }
}
-
- private findRootPrototype(source: any, name: any) {
- var proto = source;
- do {
- proto = Object.getPrototypeOf(proto);
- } while (proto !== null && !proto.hasOwnProperty(name));
- return proto;
+ }
+
+ setFullScreen(fullScreen: boolean): void {
+ throw new Error('Method not implemented.');
+ }
+
+ private updateiOSLockScreen() {
+ UINavigationController.attemptRotationToDeviceOrientation();
+ var app: UIViewController = Frame.topmost().ios.controller;
+ var shouldAutorotate = this.findRootPrototype(app, 'shouldAutorotate');
+ var shouldAutorotateToInterfaceOrientation = this.findRootPrototype(app, 'shouldAutorotateToInterfaceOrientation');
+
+ Object.defineProperty(shouldAutorotate, 'shouldAutorotate', {
+ get: () => {
+ //console.log("shouldAutorotate rotate");
+ return !this.lockRotation;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+
+ Object.defineProperty(shouldAutorotateToInterfaceOrientation, 'shouldAutorotateToInterfaceOrientation', {
+ get: () => {
+ //console.log("shouldAutorotateToInterfaceOrientation rotate");
+ return !this.lockRotation;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+ if (parseFloat(Device.osVersion) >= 16) {
+ var supportedInterfaceOrientations = this.findRootPrototype(app, 'supportedInterfaceOrientations');
+ Object.defineProperty(supportedInterfaceOrientations, 'supportedInterfaceOrientations', {
+ get: () => {
+ return this.interfaceOrientationMask;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+ }
+ }
+
+ private getMakFormInterfaceOrientation() {
+ const orientation = UIApplication.sharedApplication?.windows?.firstObject?.windowScene?.interfaceOrientation;
+ switch (orientation) {
+ case UIInterfaceOrientation.LandscapeLeft:
+ return UIInterfaceOrientationMask.LandscapeLeft;
+ case UIInterfaceOrientation.LandscapeRight:
+ return UIInterfaceOrientationMask.LandscapeRight;
+ case UIInterfaceOrientation.Portrait:
+ return UIInterfaceOrientationMask.Portrait;
+ case UIInterfaceOrientation.PortraitUpsideDown:
+ return UIInterfaceOrientationMask.PortraitUpsideDown;
+ default:
+ return UIInterfaceOrientationMask.Portrait;
}
-}
\ No newline at end of file
+ }
+
+ private findRootPrototype(source: any, name: any) {
+ var proto = source;
+ do {
+ proto = Object.getPrototypeOf(proto);
+ } while (proto !== null && !proto.hasOwnProperty(name));
+ return proto;
+ }
+}
diff --git a/packages/nativescript-orientation/package.json b/packages/nativescript-orientation/package.json
index 01f9416..5b8df86 100644
--- a/packages/nativescript-orientation/package.json
+++ b/packages/nativescript-orientation/package.json
@@ -1,6 +1,6 @@
{
- "name": "@vallemar/nativescript-orientation",
- "version": "1.0.0",
+ "name": "@nativescript-use/nativescript-orientation",
+ "version": "0.0.3",
"description": "Add a plugin description",
"main": "index",
"typings": "index.d.ts",
@@ -12,7 +12,7 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/NativeScript/plugins.git"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
},
"keywords": [
"NativeScript",
@@ -26,10 +26,10 @@
"email": "oss@nativescript.org"
},
"bugs": {
- "url": "https://github.com/NativeScript/plugins/issues"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
},
"license": "Apache-2.0",
- "homepage": "https://github.com/NativeScript/plugins",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
"readmeFilename": "README.md",
"bootstrapper": "@nativescript/plugin-seed"
}
diff --git a/packages/nativescript-orientation/project.json b/packages/nativescript-orientation/project.json
index 61ad1c7..878872f 100644
--- a/packages/nativescript-orientation/project.json
+++ b/packages/nativescript-orientation/project.json
@@ -5,12 +5,13 @@
"sourceRoot": "packages/nativescript-orientation",
"targets": {
"build": {
- "executor": "@nrwl/js:tsc",
+ "executor": "@nx/js:tsc",
"options": {
"outputPath": "dist/packages/nativescript-orientation",
"tsConfig": "packages/nativescript-orientation/tsconfig.json",
"packageJson": "packages/nativescript-orientation/package.json",
"main": "packages/nativescript-orientation/index.d.ts",
+ "generatePackageJson": false,
"assets": [
"packages/nativescript-orientation/*.md",
"packages/nativescript-orientation/index.d.ts",
@@ -32,14 +33,10 @@
"build.all": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "node tools/scripts/build-finish.ts nativescript-orientation"
- ],
+ "commands": ["node tools/scripts/build-finish.ts nativescript-orientation"],
"parallel": false
},
- "outputs": [
- "dist/packages/nativescript-orientation"
- ],
+ "outputs": ["dist/packages/nativescript-orientation"],
"dependsOn": [
{
"target": "build.all",
@@ -54,18 +51,14 @@
"focus": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "nx g @nativescript/plugin-tools:focus-packages nativescript-orientation"
- ],
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-orientation"],
"parallel": false
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
- "lintFilePatterns": [
- "packages/nativescript-orientation/**/*.ts"
- ]
+ "lintFilePatterns": ["packages/nativescript-orientation/**/*.ts"]
}
}
},
diff --git a/packages/nativescript-task/.eslintrc.json b/packages/nativescript-task/.eslintrc.json
new file mode 100644
index 0000000..53c06c8
--- /dev/null
+++ b/packages/nativescript-task/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*", "node_modules/**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/packages/nativescript-task/JSONfn.ts b/packages/nativescript-task/JSONfn.ts
new file mode 100644
index 0000000..30c09a6
--- /dev/null
+++ b/packages/nativescript-task/JSONfn.ts
@@ -0,0 +1,58 @@
+// https://dev.to/localazy/how-to-pass-function-to-web-workers-4ee1
+// https://github.com/vkiryukhin/jsonfn
+
+export const JSONfn = {
+ stringify(obj: any) {
+ return JSON.stringify(obj, function (key, value) {
+ var fnBody;
+ if (value instanceof Function || typeof value == 'function') {
+ fnBody = value.toString();
+
+ if (fnBody.length < 8 || fnBody.substring(0, 8) !== 'function') {
+ //this is ES6 Arrow Function
+ return '_NuFrRa_' + fnBody;
+ }
+ return fnBody;
+ }
+ if (value instanceof RegExp) {
+ return '_PxEgEr_' + value;
+ }
+ return value;
+ });
+ },
+ parse(str: any, date2obj?: any) {
+ var iso8061 = date2obj ? /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/ : false;
+
+ return JSON.parse(str, function (key, value) {
+ var prefix;
+
+ if (typeof value != 'string') {
+ return value;
+ }
+ if (value.length < 8) {
+ return value;
+ }
+
+ prefix = value.substring(0, 8);
+
+ // @ts-ignore
+ if (iso8061 && value.match(iso8061)) {
+ return new Date(value);
+ }
+ if (prefix === 'function') {
+ return eval('(' + value + ')');
+ }
+ if (prefix === '_PxEgEr_') {
+ return eval(value.slice(8));
+ }
+ if (prefix === '_NuFrRa_') {
+ return eval(value.slice(8));
+ }
+
+ return value;
+ });
+ },
+ clone(obj: any, date2obj?: any) {
+ return JSONfn.parse(JSONfn.stringify(obj), date2obj);
+ },
+};
diff --git a/packages/nativescript-task/README.md b/packages/nativescript-task/README.md
new file mode 100644
index 0000000..e7b7f4c
--- /dev/null
+++ b/packages/nativescript-task/README.md
@@ -0,0 +1,126 @@
+# @nativescript-use/nativescript-task
+
+```javascript
+npm install @nativescript-use/nativescript-task
+```
+
+A [NativeScript](https://nativescript.org/) module for simply handling background tasks via web workers.
+
+This module will initialize a worker that will be available during the lifetime of your application and will be able to execute any task on it.
+
+This lib provides online workers with promises and updates.
+
+## Examples
+### Without using dependencies
+
+```ts
+import { Task } from "@nativescript-use/nativescript-task";
+
+// TS =
+Task.start((ctx) => {
+ // ⚡ This function runs in the background
+ ctx.onProgressUpdate(false);
+ return ctx.state === 1000 ? "YES" : "NO";
+}, {
+ state: 1000,
+ onProgressUpdate(update) {
+ console.log(update.data);
+ }
+})
+ .then((result) => {
+ console.log('Result: ' + result.data); // "YES"
+ })
+ .catch((result) => {
+ console.log('ERROR: ' + result.error);
+ // result.state = 1000
+ });
+```
+
+### Using inline functions
+
+We can add local functions to run inside the worker using `attachToContextFunctions`.
+
+```ts
+import { Task, TaskContext } from "@nativescript-use/nativescript-task";
+
+const myFunction = (myNumber: number) => 5 + myNumber;
+const myOtherFunction = (myNumber: number) => 20 + myNumber;
+
+Task.start((ctx) => {
+ return myFunction(ctx.state) + myOtherFunction(ctx.state);
+}, { state: 10, attachToContextFunctions: { myFunction, myOtherFunction }})
+```
+
+
+### Using dependencies
+
+We need to define a worker with the imports that we want to have defined in our tasks. We define the file `globalWorker.ts|js` in the `src|app` folder of our project, import the modules that we want to have available and pass them to the `defineWorker` function that this library provides.
+
+```ts
+// /app/globalWorker.ts
+import '@nativescript/core/globals';
+import { defineWorker } from "@nativescript-use/nativescript-task";
+
+import { myUtils } from '@utils';
+import { otherLib } from 'other-lib';
+
+defineWorker({ imports: { myUtils, otherLib } });
+```
+
+Now access the modules defined in the globalWorker file from the context.
+
+```ts
+import { Task } from "@nativescript-use/nativescript-task";
+import { myUtils } from '@utils';
+import { otherLib } from 'other-lib';
+
+Task.start((ctx) => {
+ // access imported modules
+ return myUtils.someFunction(1000) + otherLib.otherFunction(ctx.state);
+}, { state: 1000 })
+ .then((result) => {
+ console.log('Result: ' + result.data);
+ })
+```
+
+## Global configuration
+
+```ts
+// app.ts | main.ts (entry file app)
+
+import { Task } from "@nativescript-use/nativescript-task";
+
+Task.globalWorkerConfig({
+ stickyWorker: true,
+ newWorkerIfGlobalIsUsed: true,
+ startGlobalWorker: true
+});
+
+// run app
+```
+
+- `stickyWorker` - default `true`: When set to true the plugin always keeps a worker running to launch your tasks to this worker. This saves time when launching the task since initializing a worker takes time, by default it is true to launch each task as quickly as possible. If set to false the plugin will initialize a worker and terminate each task.
+- `newWorkerIfGlobalIsUsed` - default `true`: When stickyWorker is true and we have a worker always running, if we launch a task and the main worker is running with another task, a new worker will be created to launch this task and not wait for the previous task to finish. If you disable this flag and launch another task while one is running, it will have to wait until it reaches the beginning of the queue.
+- `startGlobalWorker` - default `true`: Initialize the global worker when the configuration is set, it will be available when you launch your first task. If disabled, when the first task is launched it will have the worker creation delay.
+
+Note: when the worker execution time is mentioned we are talking about about 200ms (it is almost nothing). It's not much, but this plugin prioritizes speed, which is why we keep a `stickyWorker` always available.
+
+## Limitations
+
+* Only submit and return serializable objects and values.
+* All task functions are 'closures', what means that you CANNOT access variables outside such functions. All functions are serialized as strings and submitted to the [worker script](https://github.com/mkloubert/nativescript-tasks/blob/master/plugin/worker.js) where "external stuff" is NOT available! The only way to share data with the functions is to submit an optional and serializable "state value".
+
+Read the [official documentation](https://docs.nativescript.org/guide/multithreading) to get more information.
+
+
+For more information you can enter the [NativeScript discord server](https://discord.com/invite/RgmpGky9GR)!
+
+This plugin is largely based on https://github.com/mkloubert/nativescript-tasks
+
+## License
+
+Apache License Version 2.0
+
+Made with ❤️
+
+
diff --git a/packages/nativescript-task/defineWorker.ts b/packages/nativescript-task/defineWorker.ts
new file mode 100644
index 0000000..ae81015
--- /dev/null
+++ b/packages/nativescript-task/defineWorker.ts
@@ -0,0 +1,77 @@
+import { JSONfn } from './JSONfn';
+
+const DEFAULT_PARAM_NAME = 'internalCtx';
+
+export const defineWorker = (options: { imports?: {} } = {}) => {
+ self.onmessage = function (msg: any) {
+ const request: { id: string; func: { body: string; attachToContextFunctions?: any }; state: any; imports?: string[] } = JSON.parse(msg.data);
+ try {
+ //console.time('defineWorker');
+ //console.timeEnd('defineWorker');
+ let { paramUserName, functionString } = extractContextParamName(request.func.body);
+ const { functionStrToAttach, attachToContextFunctions } = parseAttachToContextFunctions(request.func.attachToContextFunctions, paramUserName);
+
+ functionString = injectContext(functionString, functionStrToAttach, paramUserName);
+ const func = JSONfn.parse(functionString);
+ let result;
+ if (func) {
+ result = func({
+ state: request.state,
+ ...options?.imports,
+ ...attachToContextFunctions,
+ onProgressUpdate: (dataUpdate: any) => self.postMessage(JSON.stringify({ dataUpdate: dataUpdate ?? null, id: request.id, onProgressUpdate: true })),
+ });
+ }
+
+ if (result) {
+ result = JSON.stringify({ ...{ id: request.id }, ...{ result: result } });
+ }
+ self.postMessage(result);
+ } catch (error: any) {
+ throw new Error(JSON.stringify({ id: request.id, error: error.toString() }));
+ }
+ };
+};
+
+function injectImports(functionString: string, paramUserName: string) {
+ functionString = functionString.replaceAll(/([0-9],_.*?)(.*?__WEBPACK_IMPORTED_MODULE_.*?)(__.?)/g, paramUserName + '.');
+ functionString = functionString.replaceAll(/( _.*?)(.*?__WEBPACK_IMPORTED_MODULE_.*?)(__.?)/g, ' ' + paramUserName + '.');
+ return functionString;
+}
+
+function injectFunctionToAttach(functionString: string, functionStrToAttach: string[], paramUserName: string) {
+ return functionString.replace(`_NuFrRa_(${paramUserName}) => {`, `_NuFrRa_(${paramUserName}) => {${functionStrToAttach.join(' ')}`);
+}
+
+function injectContext(functionString: string, functionStrToAttach: string[], paramUserName: string) {
+ return injectFunctionToAttach(injectImports(functionString, paramUserName), functionStrToAttach, paramUserName);
+}
+
+function extractContextParamName(functionString: string) {
+ const querySearchParam = functionString.match(/(?<=\_NuFrRa_\()(.*?)(?=\))/);
+ let paramUserName = DEFAULT_PARAM_NAME;
+
+ if (querySearchParam && querySearchParam.length > 0 && querySearchParam[0] !== '') {
+ paramUserName = querySearchParam[0];
+ } else {
+ // If the user has not defined the context parameter, it is added
+ functionString = functionString.replace('_NuFrRa_()', `_NuFrRa_(${DEFAULT_PARAM_NAME})`);
+ }
+ return { paramUserName, functionString };
+}
+
+function parseAttachToContextFunctions(attachToContextFunctions: any, paramUserName: string) {
+ const keyFunctionst = Object.keys(attachToContextFunctions);
+ const functionStrToAttach: string[] = [];
+ var attachToContextFunctionsResult = {};
+ if (attachToContextFunctions && keyFunctionst.length > 0) {
+ attachToContextFunctionsResult = keyFunctionst.reduce((resultObject: any, keyFunction: string) => {
+ let attachFunction = injectImports(attachToContextFunctions[keyFunction], paramUserName);
+ const parseFunctionToInject = attachFunction.replace('_NuFrRa_', `const ${keyFunction} = `);
+ functionStrToAttach.push(parseFunctionToInject.substring(1, parseFunctionToInject.length - 1));
+ resultObject[keyFunction] = JSONfn.parse(attachFunction);
+ return resultObject;
+ }, {});
+ }
+ return { functionStrToAttach, attachToContextFunctions: attachToContextFunctionsResult };
+}
diff --git a/packages/nativescript-task/globalWorker.ts b/packages/nativescript-task/globalWorker.ts
new file mode 100644
index 0000000..d94d5d6
--- /dev/null
+++ b/packages/nativescript-task/globalWorker.ts
@@ -0,0 +1,4 @@
+import '@nativescript/core/globals';
+import { defineWorker } from './defineWorker';
+
+defineWorker();
diff --git a/packages/nativescript-task/index.ts b/packages/nativescript-task/index.ts
new file mode 100644
index 0000000..b2a8f1b
--- /dev/null
+++ b/packages/nativescript-task/index.ts
@@ -0,0 +1,418 @@
+import { Observable } from '@nativescript/core';
+import { JSONfn } from './JSONfn';
+export * from './defineWorker';
+
+/**
+ * Describes a task function.
+ *
+ * @param {TState} [state] The optional value to submit to the function.
+ *
+ * @return {TResult} The result of the function.
+ */
+export type TaskFunc = (ctx: TaskContext) => TResult;
+export type TaskFuncUpdate = (update: { data: TUpdate }) => void;
+
+export interface OnData {
+ data: Data;
+}
+/**
+ * Describes a task context.
+ */
+export interface TaskContext {
+ state: TState;
+ onProgressUpdate: (dataUpdate: TUpdate) => void;
+ [key: string]: any;
+}
+
+/**
+ * Describes a result of a task.
+ */
+export interface TaskResult {
+ /**
+ * The result data (on success)
+ */
+ data?: TResult;
+
+ /**
+ * The error (if occurred)
+ */
+ error?: any;
+
+ /**
+ * The submitted value.
+ */
+ state?: TState;
+}
+
+export interface TaskUpdate {
+ /**
+ * The update data (on update)
+ */
+ data: TUpdate;
+}
+
+/**
+ * List of task states.
+ */
+export enum TaskStatus {
+ Starting,
+ /**
+ * The task has been initialized but has not yet been invoked.
+ */
+ Created,
+
+ /**
+ * The task completed due to an unhandled exception.
+ */
+ Faulted,
+
+ /**
+ * The task completed execution successfully.
+ */
+ RanToCompletion,
+
+ /**
+ * The task is running but has not yet completed.
+ */
+ Running,
+
+ /**
+ * The task has been scheduled for execution but has not yet begun executing.
+ */
+ WaitingToRun,
+}
+type GeneralCallback = ((data: any | undefined) => void) | undefined;
+export type GlobalWorkerConfiguration = { stickyWorker?: boolean; newWorkerIfGlobalIsUsed?: boolean; startGlobalWorker?: boolean };
+export type DataWorker = { worker?: Worker; isGlobal: boolean; running: boolean; globalResolve?: { [key: string]: GeneralCallback }; globalReject?: { [key: string]: GeneralCallback }; globalOnUpdate?: { [key: string]: GeneralCallback } };
+let dataGlobalWorker: DataWorker = { worker: null!, isGlobal: true, running: false, globalResolve: {}, globalReject: {}, globalOnUpdate: {} };
+let globalConfiguration: GlobalWorkerConfiguration = { stickyWorker: true, newWorkerIfGlobalIsUsed: true, startGlobalWorker: true };
+
+/**
+ * A task.
+ */
+export class Task extends Observable {
+ /**
+ * Stores the function to invoke.
+ */
+ protected readonly _FUNC: TaskFunc;
+ protected readonly _FUNC_UPDATE?: TaskFuncUpdate;
+ /**
+ * Stores the error of the last execution.
+ */
+ protected _error: any;
+ /**
+ * Stores the current task state.
+ */
+ protected _status: TaskStatus = TaskStatus.Starting;
+
+ protected dataWorker: DataWorker = { worker: null!, isGlobal: false, running: false };
+ protected id = '';
+ /**
+ * Initializes a new instance of that class.
+ *
+ * @param {TaskFunc} func The function to invoke.
+ */
+ constructor(func: TaskFunc, funcUptade?: TaskFuncUpdate) {
+ super();
+ if (func !== null && func !== undefined) {
+ if (typeof func !== 'function') {
+ throw "'func' must be a function!";
+ }
+ }
+
+ this._FUNC = func;
+ this._FUNC_UPDATE = funcUptade;
+ this.updateStatus(TaskStatus.Created);
+ }
+
+ public static globalWorkerConfig(options: GlobalWorkerConfiguration) {
+ globalConfiguration = { ...globalConfiguration, ...options };
+ if (globalConfiguration.startGlobalWorker) {
+ Task.initGlobalWorker();
+ }
+ }
+
+ public static initGlobalWorker(): Worker {
+ if (dataGlobalWorker.worker == null) {
+ dataGlobalWorker.worker = new Worker('~/globalWorker');
+ }
+ return dataGlobalWorker.worker;
+ }
+
+ private newWorker() {
+ return new Worker('~/globalWorker');
+ }
+
+ public static finishGlobalWorker() {
+ dataGlobalWorker.worker?.terminate();
+ dataGlobalWorker.worker = null!;
+ dataGlobalWorker.running = false;
+ }
+
+ /**
+ * Creates a new task.
+ *
+ * @param {TaskFunc} func The function to invoke.
+ *
+ * @return {Task} The new task.
+ */
+ public static newTask(func: TaskFunc, onProgressUpdate?: TaskFuncUpdate): Task {
+ return new Task(func, onProgressUpdate);
+ }
+
+ /**
+ * Creates and starts a new task.
+ *
+ * @param {TaskFunc} func The function to invoke.
+ * @param {TState} [state] The optional value / object for the execution.
+ *
+ * @return {Promise} The promise.
+ */
+ public static start(func: TaskFunc, options?: { state?: TState; onProgressUpdate?: TaskFuncUpdate; attachToContextFunctions?: {}; performance?: boolean }): Promise> {
+ return Task.newTask(func, options?.onProgressUpdate).start(options);
+ }
+
+ /**
+ * Gets the error of the last execution.
+ */
+ public get error(): any {
+ return this._error;
+ }
+
+ /**
+ * Gets the underyling function to invoke.
+ */
+ public get func(): TaskFunc {
+ return this._FUNC;
+ }
+
+ /**
+ * Gets the underyling upudate function to invoke.
+ */
+ public get funcUpdate(): TaskFuncUpdate | undefined {
+ return this._FUNC_UPDATE;
+ }
+
+ public getWorker(): DataWorker {
+ if (globalConfiguration.newWorkerIfGlobalIsUsed && dataGlobalWorker.running) {
+ return { worker: this.newWorker(), isGlobal: false, running: false };
+ }
+
+ if (dataGlobalWorker.worker === null) {
+ dataGlobalWorker.worker = this.newWorker();
+ return { worker: dataGlobalWorker.worker, isGlobal: true, running: false };
+ } else {
+ return { worker: dataGlobalWorker.worker, isGlobal: true, running: false };
+ }
+ }
+
+ /**
+ * Starts the task.
+ *
+ * @param {TState} [state] The optional value to submit to the function.
+ *
+ * @return {Promise>} The promise.
+ */
+
+ public start(options?: { state?: TState; attachToContextFunctions?: { [key: string]: any }; performance?: boolean }): Promise> {
+ this.id = Date.now().toString();
+ let me = this;
+
+ return new Promise>((resolve, reject) => {
+ let completed = (id: string, err: any, data?: TResult) => {
+ if (err) {
+ const rejectFunction = me.getReject(id, reject);
+ if (rejectFunction) {
+ rejectFunction({
+ error: err,
+ state: options?.state,
+ });
+ }
+ } else {
+ const resolveFunction = me.getResolve(id, resolve);
+ if (resolveFunction) {
+ resolveFunction({
+ data: data,
+ state: options?.state,
+ });
+ }
+ }
+ if (options?.performance) {
+ console.timeEnd('RunWorker');
+ }
+ me.removeGlobalCallback(id);
+ me.checkTerminateWorker(data);
+ me.updateError(err);
+ };
+
+ switch (me._status) {
+ case TaskStatus.Created:
+ case TaskStatus.Faulted:
+ case TaskStatus.RanToCompletion:
+ break;
+
+ default:
+ completed('', new Error(`Cannot start while in '${TaskStatus[me._status]}' state!`));
+ return;
+ }
+
+ try {
+ me.updateStatus(TaskStatus.WaitingToRun);
+ me.dataWorker = me.getWorker();
+ const worker: Worker = me.dataWorker.worker as Worker;
+ me.dataWorker.running = true;
+ if (me.dataWorker.isGlobal && dataGlobalWorker.globalResolve && dataGlobalWorker.globalReject && dataGlobalWorker.globalOnUpdate) {
+ dataGlobalWorker.running = true;
+ dataGlobalWorker.globalResolve[me.id] = resolve;
+ dataGlobalWorker.globalReject[me.id] = reject;
+ dataGlobalWorker.globalOnUpdate[me.id] = me._FUNC_UPDATE;
+ }
+
+ worker.onmessage = function (msg) {
+ let message = msg.data;
+ let executionId = '';
+ if (message) {
+ message = JSON.parse(message);
+ executionId = message.id;
+ }
+
+ if (message?.onProgressUpdate === true) {
+ const onUpdateFuncion = me.getOnUpdate(executionId);
+ if (onUpdateFuncion) {
+ onUpdateFuncion({ data: message.dataUpdate });
+ }
+ } else {
+ me.updateStatus(TaskStatus.RanToCompletion);
+ completed(executionId, null, message.result);
+ }
+ };
+
+ worker.onerror = function (err) {
+ const idExecution = JSON.parse(err.message.replace('Uncaught Error: ', ''))?.id;
+ me.updateStatus(TaskStatus.Faulted);
+ completed(idExecution, err);
+ };
+
+ let func: any;
+
+ if (me._FUNC) {
+ func = {};
+ func.body = JSONfn.stringify(me._FUNC);
+ if (options?.attachToContextFunctions && Object.keys(options?.attachToContextFunctions).length > 0) {
+ // @ts-ignore
+ const functionsToAttach = Object.keys(options.attachToContextFunctions).reduce((resultObject: any, keyFunction: string) => {
+ // @ts-ignore
+ resultObject[keyFunction] = JSONfn.stringify(options.attachToContextFunctions[keyFunction]);
+ return resultObject;
+ }, {});
+ func.attachToContextFunctions = functionsToAttach;
+ }
+ }
+
+ if (options?.performance) {
+ console.time('RunUI');
+ // @ts-ignore
+ me._FUNC({ state: options?.state, ...options?.attachToContextFunctions });
+ console.timeEnd('RunUI');
+ console.time('RunWorker');
+ }
+ me.updateStatus(TaskStatus.Running);
+
+ worker.postMessage(
+ JSON.stringify({
+ id: me.id,
+ func: func,
+ state: options?.state,
+ })
+ );
+ } catch (e) {
+ console.log(e);
+ me.updateStatus(TaskStatus.Faulted);
+ completed(me.id, e);
+ }
+ });
+ }
+
+ private getReject(id: string, reject: (data: any) => void) {
+ if (this.dataWorker.isGlobal) {
+ return dataGlobalWorker.globalReject ? dataGlobalWorker.globalReject[id] : null;
+ }
+ return reject;
+ }
+ private getResolve(id: string, resolve: (data: any) => void) {
+ if (this.dataWorker.isGlobal) {
+ return dataGlobalWorker.globalResolve ? dataGlobalWorker.globalResolve[id] : null;
+ }
+ return resolve;
+ }
+
+ private getOnUpdate(id: string) {
+ if (this.dataWorker.isGlobal) {
+ return dataGlobalWorker.globalOnUpdate ? dataGlobalWorker.globalOnUpdate[id] : null;
+ }
+ return this._FUNC_UPDATE;
+ }
+
+ private removeGlobalCallback(id: string) {
+ if (dataGlobalWorker.globalResolve && dataGlobalWorker.globalResolve[id]) delete dataGlobalWorker.globalResolve[id];
+ if (dataGlobalWorker.globalReject && dataGlobalWorker.globalReject[id]) delete dataGlobalWorker.globalReject[id];
+ if (dataGlobalWorker.globalOnUpdate && dataGlobalWorker.globalOnUpdate[id]) delete dataGlobalWorker.globalOnUpdate[id];
+ }
+
+ private checkTerminateWorker(result: any) {
+ if ((!this.dataWorker.isGlobal && result?.onProgressUpdate !== true) || (!globalConfiguration.stickyWorker && dataGlobalWorker.isGlobal && dataGlobalWorker.globalResolve && Object.keys(dataGlobalWorker.globalResolve).length === 0)) {
+ this.dataWorker.worker?.terminate();
+ this.dataWorker.worker = null!;
+ if (this.dataWorker.isGlobal) {
+ Task.finishGlobalWorker();
+ }
+ }
+ if (result?.onProgressUpdate !== true) {
+ this.dataWorker.running = false;
+ if (this.dataWorker.isGlobal && dataGlobalWorker.globalResolve && Object.keys(dataGlobalWorker.globalResolve).length === 0) dataGlobalWorker.running = false;
+ }
+ }
+
+ /**
+ * Gets the current status.
+ */
+ public get status(): TaskStatus {
+ return this._status;
+ }
+
+ /**
+ * Updates the error value.
+ *
+ * @param {TaskStatus} newValue The new value.
+ *
+ * @return {boolean} Property change has been raised for 'error' property or not.
+ */
+ protected updateError(newValue: any): boolean {
+ if (newValue !== this._error) {
+ this._error = newValue;
+
+ this.notifyPropertyChange('error', newValue);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Updates the current status.
+ *
+ * @param {TaskStatus} newValue The new value.
+ *
+ * @return {boolean} Property change has been raised for 'status' property or not.
+ */
+ protected updateStatus(newValue: TaskStatus): boolean {
+ if (newValue !== this._status) {
+ this._status = newValue;
+
+ this.notifyPropertyChange('status', newValue);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/packages/nativescript-task/nativescript.webpack.js b/packages/nativescript-task/nativescript.webpack.js
new file mode 100644
index 0000000..06b74cc
--- /dev/null
+++ b/packages/nativescript-task/nativescript.webpack.js
@@ -0,0 +1,14 @@
+module.exports = (webpack) => {
+ webpack.chainWebpack(
+ (config, env) => {
+ const fs = require('fs');
+ const filePath = `./${env.appPath}/globalWorker.js`;
+ const filePathTs = `./${env.appPath}/globalWorker.ts`;
+ if (!fs.existsSync(filePath) && !fs.existsSync(filePathTs)) {
+ const path = require('path');
+ config.resolve.alias.set('~/globalWorker', path.resolve(__dirname, 'globalWorker.js'));
+ }
+ },
+ { order: -2 }
+ );
+};
diff --git a/packages/nativescript-task/package.json b/packages/nativescript-task/package.json
new file mode 100644
index 0000000..f94bb29
--- /dev/null
+++ b/packages/nativescript-task/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "@nativescript-use/nativescript-task",
+ "version": "0.0.11",
+ "description": "Multiprocessing task in background",
+ "main": "index",
+ "typings": "index.d.ts",
+ "nativescript": {
+ "platforms": {
+ "ios": "6.0.0",
+ "android": "6.0.0"
+ }
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
+ },
+ "keywords": [
+ "NativeScript",
+ "JavaScript",
+ "TypeScript",
+ "iOS",
+ "Android",
+ "Multiprocessing",
+ "Thread",
+ "Task"
+ ],
+ "author": {
+ "name": "Juan de Dios Martínez Vallejo",
+ "email": "oss@nativescript.org"
+ },
+ "bugs": {
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
+ },
+ "license": "Apache-2.0",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
+ "readmeFilename": "README.md",
+ "bootstrapper": "@nativescript/plugin-seed",
+ "devDependencies": {
+ "@nativescript/webpack": "^5.0.8"
+ }
+}
diff --git a/packages/nativescript-vueuse/project.json b/packages/nativescript-task/project.json
similarity index 51%
rename from packages/nativescript-vueuse/project.json
rename to packages/nativescript-task/project.json
index 067d1cd..cf0550b 100644
--- a/packages/nativescript-vueuse/project.json
+++ b/packages/nativescript-task/project.json
@@ -1,23 +1,24 @@
{
- "name": "nativescript-vueuse",
+ "name": "nativescript-task",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
- "sourceRoot": "packages/nativescript-vueuse",
+ "sourceRoot": "packages/nativescript-task",
"targets": {
"build": {
- "executor": "@nrwl/js:tsc",
+ "executor": "@nx/js:tsc",
"options": {
- "outputPath": "dist/packages/nativescript-vueuse",
- "tsConfig": "packages/nativescript-vueuse/tsconfig.json",
- "packageJson": "packages/nativescript-vueuse/package.json",
- "main": "packages/nativescript-vueuse/index.d.ts",
+ "outputPath": "dist/packages/nativescript-task",
+ "tsConfig": "packages/nativescript-task/tsconfig.json",
+ "packageJson": "packages/nativescript-task/package.json",
+ "main": "packages/nativescript-task/index.d.ts",
+ "generatePackageJson": false,
"assets": [
- "packages/nativescript-vueuse/*.md",
- "packages/nativescript-vueuse/index.d.ts",
+ "packages/nativescript-task/*.md",
+ "packages/nativescript-task/index.d.ts",
"LICENSE",
{
"glob": "**/*",
- "input": "packages/nativescript-vueuse/platforms/",
+ "input": "packages/nativescript-task/platforms/",
"output": "./platforms/"
}
],
@@ -32,14 +33,10 @@
"build.all": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "node tools/scripts/build-finish.ts nativescript-vueuse"
- ],
+ "commands": ["node tools/scripts/build-finish.ts nativescript-task"],
"parallel": false
},
- "outputs": [
- "dist/packages/nativescript-vueuse"
- ],
+ "outputs": ["dist/packages/nativescript-task"],
"dependsOn": [
{
"target": "build.all",
@@ -54,18 +51,14 @@
"focus": {
"executor": "nx:run-commands",
"options": {
- "commands": [
- "nx g @nativescript/plugin-tools:focus-packages nativescript-vueuse"
- ],
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages nativescript-task"],
"parallel": false
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
- "lintFilePatterns": [
- "packages/nativescript-vueuse/**/*.ts"
- ]
+ "lintFilePatterns": ["packages/nativescript-task/**/*.ts"]
}
}
},
diff --git a/packages/nativescript-task/references.d.ts b/packages/nativescript-task/references.d.ts
new file mode 100644
index 0000000..22bac92
--- /dev/null
+++ b/packages/nativescript-task/references.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/nativescript-task/tsconfig.json b/packages/nativescript-task/tsconfig.json
new file mode 100644
index 0000000..78580eb
--- /dev/null
+++ b/packages/nativescript-task/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "rootDir": ".",
+ "allowJs": true
+ },
+ "exclude": ["**/*.spec.ts", "**/*.test.ts", "angular"],
+ "include": ["**/*.ts", "references.d.ts", "nativescript.webpack.js"]
+}
diff --git a/packages/nativescript-vueuse/README.md b/packages/nativescript-vueuse/README.md
deleted file mode 100644
index 0698ce5..0000000
--- a/packages/nativescript-vueuse/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# @vallemar/nativescript-vueuse
-
-```javascript
-npm install @vallemar/nativescript-vueuse
-```
-
-## Usage
-
-// TODO
-
-## License
-
-Apache License Version 2.0
diff --git a/packages/nativescript-vueuse/index.d.ts b/packages/nativescript-vueuse/index.d.ts
deleted file mode 100644
index 200582f..0000000
--- a/packages/nativescript-vueuse/index.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export * from "./src/unrefView";
-export * from "./src/useClipboard";
-export * from "./src/useColorMode";
-export * from "./src/useColorPalette";
-export * from "./src/useElementSize";
-export * from "./src/useEventListener";
-export * from "./src/useKeyboard";
-export * from "./src/useRootLayout";
-export * from "./src/useScreenOrientation";
-export * from "./src/useStorage";
-export * from "./src/types";
-export * from "./src/onApplicationMounted";
diff --git a/packages/nativescript-vueuse/index.ts b/packages/nativescript-vueuse/index.ts
deleted file mode 100644
index 4cfa345..0000000
--- a/packages/nativescript-vueuse/index.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Functions */
-export * from "./src/unrefView"
-export * from "./src/useClipboard"
-export * from "./src/useColorMode"
-export * from "./src/useColorPalette"
-export * from "./src/useElementSize"
-export * from "./src/useEventListener"
-export * from "./src/useKeyboard"
-export * from "./src/useRootLayout"
-export * from "./src/useScreenOrientation"
-export * from "./src/useStorage"
-export * from "./src/types"
-
-/* Global hooks */
-export * from "./src/onApplicationMounted"
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/references.d.ts b/packages/nativescript-vueuse/references.d.ts
deleted file mode 100644
index 98c5393..0000000
--- a/packages/nativescript-vueuse/references.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/globalState.ts b/packages/nativescript-vueuse/src/globalState.ts
deleted file mode 100644
index cdbfb91..0000000
--- a/packages/nativescript-vueuse/src/globalState.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { effectScope } from "nativescript-vue"
-
-export type AnyFn = (...args: any[]) => any
-export function createGlobalState(
- stateFactory: Fn,
- ): Fn {
- let initialized = false
- let state: any
- const scope = effectScope(true)
-
- return ((...args: any[]) => {
- if (!initialized) {
- state = scope.run(() => stateFactory(...args))!
- initialized = true
- }
- return state
- }) as Fn
- }
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/onApplicationMounted/index.ts b/packages/nativescript-vueuse/src/onApplicationMounted/index.ts
deleted file mode 100644
index 10431ce..0000000
--- a/packages/nativescript-vueuse/src/onApplicationMounted/index.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Application, Frame } from "@nativescript/core"
-
-export const onApplicationMounted = (callback: () => void, immediateCallback?: () => void) => {
- if (Frame.topmost()) {
- immediateCallback ? immediateCallback(): null;
- callback();
- } else {
- const run = () => {
- callback();
- Application.off("launch", run);
- };
- Application.on("launch", run);
- }
-}
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/types.ts b/packages/nativescript-vueuse/src/types.ts
deleted file mode 100644
index fa8ce88..0000000
--- a/packages/nativescript-vueuse/src/types.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import {View} from "@nativescript/core";
-import {Ref} from "nativescript-vue"
-
-export type ViewRef = Ref<{ nativeView?: T }>
diff --git a/packages/nativescript-vueuse/src/unrefView/index.md b/packages/nativescript-vueuse/src/unrefView/index.md
deleted file mode 100644
index a9f67c2..0000000
--- a/packages/nativescript-vueuse/src/unrefView/index.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-# unrefView
-
-Extract a NativeScript view from a Ref
-
-## Usage
-
-```vue
-
-
-
-
-
-
-
-```
-
-
-## Type declaration
-```ts
-import { View } from "@nativescript/core";
-import { ViewRef } from "@vallemar/nativescript-vueuse";
-/**
- * Utility. Get View from Ref.
- *
- * @param target
- */
-export declare function unrefView(target: ViewRef): T | undefined;
-```
diff --git a/packages/nativescript-vueuse/src/unrefView/index.ts b/packages/nativescript-vueuse/src/unrefView/index.ts
deleted file mode 100644
index 95f0571..0000000
--- a/packages/nativescript-vueuse/src/unrefView/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { View } from "@nativescript/core"
-import { ViewRef } from "../types"
-
-/**
- * Utility. Get View from Ref.
- *
- * @param target
- */
-export function unrefView(
- target: ViewRef,
-) {
- return target?.value?.nativeView;
-}
diff --git a/packages/nativescript-vueuse/src/useClipboard/index.ts b/packages/nativescript-vueuse/src/useClipboard/index.ts
deleted file mode 100644
index 61179f8..0000000
--- a/packages/nativescript-vueuse/src/useClipboard/index.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { onUnmounted, ref } from "nativescript-vue"
-import { Clipboard } from "@vallemar/nativescript-clipboard";
-import { onApplicationMounted } from "../onApplicationMounted";
-
-/**
- * Reactive Clipboard API. Provides the ability to respond to clipboard commands.
- *
- */
-export function useClipboard(options?: { sync?: boolean }
-) {
- const {
- sync = false
- } = options ?? {}
-
- let clipboard: Clipboard | undefined;
-
- const copied = ref(false);
- const text = ref("");
-
- const copy = (text: string) => {
- copied.value = clipboard?.copy(text) ?? false
- }
-
- const read = () => {
- text.value = clipboard?.read() ?? "";
- return text.value;
- }
-
- onApplicationMounted(() => {
- if (!clipboard)
- clipboard = new Clipboard();
- if (sync) {
- text.value = clipboard.read();
- clipboard.onCopy((copyText) => {
- text.value = copyText;
- })
- }
- }, () => {
- clipboard = new Clipboard();
- if (sync) {
- text.value = clipboard.read();
- }
- })
-
- onUnmounted(() => {
- clipboard?.offCopy();
- })
-
- return {
- text,
- copied,
- copy,
- read
- }
-}
-
diff --git a/packages/nativescript-vueuse/src/useColorMode/index.ts b/packages/nativescript-vueuse/src/useColorMode/index.ts
deleted file mode 100644
index 19a56aa..0000000
--- a/packages/nativescript-vueuse/src/useColorMode/index.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-import { Application, CSSUtils, Utils, isAndroid, Frame } from "@nativescript/core"
-import { ref, Ref, watch, computed, onUnmounted, getCurrentInstance, readonly } from "nativescript-vue"
-import { useStorage } from "../useStorage"
-import { setAutoSystemAppearanceChanged, systemAppearanceChanged } from "@nativescript/core/application"
-import removeSystemCssClass = CSSUtils.removeSystemCssClass;
-import { createGlobalState } from "../globalState";
-
-export type BasicColorMode = 'light' | 'dark'
-export type BasicColorSchema = BasicColorMode | 'auto'
-export interface UseColorModeOptions {
- /**
- * The initial color mode
- *
- * @default 'auto'
- */
- initialValue?: T | BasicColorSchema
-
- /**
- * Prefix when adding value to the attribute
- */
- modes?: T[] | BasicColorSchema[]
-
- /**
- * A custom handler for handle the updates.
- * When specified, the default behavior will be overridden.
- *
- * @default undefined
- */
- onChanged?: (mode: T | BasicColorMode) => void
-
- /**
- * Key to persist the data into ApplicationSettings.
- *
- * Pass `null` to disable persistence
- *
- * @default 'nativevueuse-color-scheme'
- */
- storageKey?: string | null
-}
-
-const useGlobalState = createGlobalState((storageKey: string, initialValue: string, themes: string[]) => {
- const storage = useStorage();
- const system = ref(getSystemTheme())
- const schema = ref(storage.getString(storageKey!, initialValue.toString())) as Ref;
- const modes = ref(themes);
- return { system, schema, modes }
-})
-
-export function useColorMode(options: UseColorModeOptions = {},) {
- const {
- initialValue = 'auto',
- storageKey = 'nativevueuse-color-scheme'
- } = options
-
- const storage = useStorage();
-
- const { system, schema, modes } = useGlobalState(storageKey!, initialValue, ["auto", "light", "dark", ...options.modes ?? []])
-
- const theme = computed(() =>
- schema.value === 'auto'
- ? system.value
- : schema.value,
- );
- let internalSchema = schema.value;
-
- Application.on('displayed', () => {
- processTheme();
- });
- Application.on('systemAppearanceChanged', () => {
- processTheme();
- });
-
- if (getCurrentInstance()) {
- onUnmounted(() => {
- Application.off('displayed', processTheme)
- Application.off('systemAppearanceChanged', processTheme)
- })
- }
-
- function processTheme() {
- system.value = getSystemTheme();
- if (schema.value === "auto") {
- applyTheme(system.value);
- } else {
- applyTheme(schema.value);
- }
- }
-
- function applyTheme(themeToApply: T | BasicColorSchema) {
- const rootView = Application.getRootView();
- if (rootView && !rootView.className?.includes(getClassFromTheme(themeToApply))) {
- schema.value = themeToApply;
- const rootViewClass = new Set();
- (Array.from(rootView.cssClasses).join(" ") ?? " ").split(/\s+/).forEach((v) => v && rootViewClass.add(v));
-
- modes.value.forEach(theme => {
- removeSystemCssClass(getClassFromTheme(theme))
- rootViewClass.delete(getClassFromTheme(theme));
- })
-
- let applyTheme = themeToApply;
- if (themeToApply.toLocaleLowerCase().trim() === "auto") {
- applyTheme = getSystemTheme();
- setAutoSystemAppearanceChanged(true);
- systemAppearanceChanged(rootView, getSystemTheme()!);
- } else {
- setAutoSystemAppearanceChanged(false);
- }
- rootViewClass.add(getClassFromTheme(applyTheme));
-
- rootView.className = Array.from(rootViewClass).join(" ")
- const frame = Frame.topmost();
- frame.backStack.forEach(backStack => backStack.resolvedPage?._onCssStateChange())
- rootView._getRootModalViews()?.forEach((view) => {
- view?._onCssStateChange();
- });
- storage.setString(storageKey!, themeToApply);
-
- console.log("Apply: " + getClassFromTheme(themeToApply));
- }
-
- if(rootView && schema.value !== internalSchema){
- internalSchema = schema.value;
- if (options.onChanged) {
- options.onChanged(theme.value);
- }
- }
- }
-
- watch(schema, () => {
- applyTheme(schema.value)
- })
-
- processTheme();
-
- return {
- schema,
- system: readonly(system),
- theme: readonly(theme),
- modes: readonly(modes)
- }
-}
-
-const getClassFromTheme = (theme: string) => CSSUtils.CLASS_PREFIX + theme.toLocaleLowerCase().trim()
-function getSystemTheme(): BasicColorMode {
- if (isAndroid) {
- const nightModeFlags = Utils.android.getApplicationContext().getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK;
- switch (nightModeFlags) {
- case android.content.res.Configuration.UI_MODE_NIGHT_YES:
- return "dark"
- case android.content.res.Configuration.UI_MODE_NIGHT_NO:
- return "light"
- default:
- return "light"
- //case android.content.res.Configuration.UI_MODE_NIGHT_UNDEFINED:
-
- }
- } else {
- return UITraitCollection.currentTraitCollection.userInterfaceStyle === UIUserInterfaceStyle.Light ? "light" : "dark";
- }
-}
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/useColorPalette/index.ts b/packages/nativescript-vueuse/src/useColorPalette/index.ts
deleted file mode 100644
index 31e4cf2..0000000
--- a/packages/nativescript-vueuse/src/useColorPalette/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import type { Color } from "@nativescript/core"
-import { Ref, ref } from "nativescript-vue"
-import { useColorMode } from "../useColorMode";
-import { createGlobalState } from "../globalState";
-
-export type PaletteColor = { theme: T, colors: S }
-export interface UseColorPaletteOptions {
- /**
- * The initial palettes
- *
- * @default 'auto'
- */
- palettes?: PaletteColor[]
-
- /**
- * A custom handler for handle the updates.
- *
- * @default undefined
- */
- onChanged?: (palette: PaletteColor) => void
-}
-
-const useGlobalState = createGlobalState((initialPalettes: PaletteColor[] | undefined) => {
- const palettes = ref(initialPalettes) as Ref[] | undefined>;
-
- return { palettes }
-})
-
-export function useColorPalette(options: UseColorPaletteOptions = {},) {
-
- const palette = ref>();
- const { palettes } = useGlobalState(options.palettes);
-
- const { theme } = useColorMode({
- modes: palettes.value?.map(palette => palette.theme) ?? [],
- onChanged: (theme) => {
- palette.value = findPaletteByTheme(palettes.value, theme);
- if (options.onChanged && palette.value) {
- options.onChanged(palette.value);
- }
- }
- });
-
- palette.value = findPaletteByTheme(palettes.value, theme.value);
-
- return {
- palette
- }
-}
-
-const findPaletteByTheme = (palettes: PaletteColor[] | undefined, theme: string) => palettes?.find(palette => palette.theme === theme);
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/useElementSize/index.ts b/packages/nativescript-vueuse/src/useElementSize/index.ts
deleted file mode 100644
index a934d72..0000000
--- a/packages/nativescript-vueuse/src/useElementSize/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { ref, onMounted } from "nativescript-vue"
-import { unrefView } from "../unrefView"
-import { ViewRef } from "../types"
-import { CoreTypes } from "@nativescript/core/core-types";
-
-export type SizeDIP = {
- width: CoreTypes.dip,
- height: CoreTypes.dip,
-}
-/**
- * Reactive size of a NativeScript element.
- *
- * @param target
- * @param options
- */
-export function useElementSize(
- target: ViewRef,
- options?: { onChange?: (size: SizeDIP) => void, initialSize?: SizeDIP },
-) {
- const {
- initialSize = { width: 0, height: 0 },
- } = options ?? {}
-
- const width = ref(initialSize.width)
- const height = ref(initialSize.height)
-
- function layoutChanged() {
- const size = unrefView(target)?.getActualSize() as SizeDIP;
- if(size){
- width.value = size.width;
- height.value = size.height;
- if (options?.onChange) {
- options.onChange(size);
- }
- }
- }
-
- onMounted(() => {
- const view = unrefView(target);
- if(view){
- view.on("layoutChanged", layoutChanged)
- view.on("unloaded", () => {
- view.off("layoutChanged", layoutChanged)
- })
- }
- })
-
- return {
- width,
- height,
- }
-}
-
diff --git a/packages/nativescript-vueuse/src/useEventListener/index.ts b/packages/nativescript-vueuse/src/useEventListener/index.ts
deleted file mode 100644
index 818caff..0000000
--- a/packages/nativescript-vueuse/src/useEventListener/index.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { onMounted, onUnmounted } from "nativescript-vue"
-import { unrefView } from "../unrefView"
-import { ViewRef } from "../types"
-import {EventData, GestureEventData, ShownModallyData, View} from "@nativescript/core"
-
-type ViewEventData = Omit & { object: T }
-type ViewGestureEventData = Omit & { object: T }
-type ViewShownModallyData = Omit & { object: T }
-
-interface Event{
- /* Lifecycle */
- loaded?: (eventData: ViewEventData ) => void,
- unloaded?: (eventData: ViewEventData) => void,
- layoutChanged?: (eventData: ViewEventData) => void,
- /* Gesture */
- tap?: (eventData: ViewGestureEventData) => void,
- doubleTap?: (eventData: ViewGestureEventData) => void,
- pinch?: (eventData: ViewGestureEventData) => void,
- pan?: (eventData: ViewGestureEventData) => void,
- swipe?: (eventData: ViewGestureEventData) => void,
- rotation?: (eventData: ViewGestureEventData) => void,
- longPress?: (eventData: ViewGestureEventData) => void,
- touch?: (eventData: ViewGestureEventData) => void,
- /* Modals */
- showingModally?: (eventData: ViewShownModallyData) => void,
- shownModally?: (eventData: ViewShownModallyData) => void,
- /* Accessibility */
- accessibilityBlur?: (eventData: ViewEventData) => void,
- accessibilityFocus?: (eventData: ViewEventData) => void,
- accessibilityFocusChanged?: (eventData: ViewEventData) => void,
- accessibilityPerformEscape?: (eventData: ViewEventData) => void,
-}
-
-/**
- * Register using view.on on mounted, and view.off automatically on unmounted.
- *
- *
- * @param target
- * @param events
- */
-export function useEventListener(
- target: ViewRef,
- events: Event,
-) {
- const el = target;
-
- const fireEvent = (onEvent: any) => (args: any) => onEvent(args);
-
- onMounted(() => {
- Object.keys(events).forEach((event) => {
- unrefView(el)?.on(event, fireEvent((events as any)[event]));
- })
- })
-
- onUnmounted(() => {
- cleanup();
- })
-
- function cleanup() {
- Object.keys(events).forEach(event => {
- unrefView(el)?.off(event, fireEvent((events as any)[event]));
- })
- }
- return {
- cleanup,
- }
-}
-
diff --git a/packages/nativescript-vueuse/src/useKeyboard/index.ts b/packages/nativescript-vueuse/src/useKeyboard/index.ts
deleted file mode 100644
index bb9e44b..0000000
--- a/packages/nativescript-vueuse/src/useKeyboard/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { onMounted, onUnmounted, readonly, ref } from "nativescript-vue"
-import { ViewRef } from "../types"
-import { unrefView } from "../unrefView";
-import { Keyboard } from "@vallemar/nativescript-keyboard";
-import { onApplicationMounted } from "../onApplicationMounted";
-
-/**
- * Reactive size of a NativeScript element.
- *
- * @param target
- * @param options
- */
-export function useKeyboard(
- options?: { onChange?: (isOpen: boolean) => void, defaultTarget?: ViewRef },
-) {
- const isOpen = ref(false);
- const keyboardCore = new Keyboard();
-
- //TODO: fix this
- onMounted(() => {
- onApplicationMounted(() => {
- keyboardCore.onChangeVisibility((status: boolean) => {
- if (isOpen.value !== status) {
- isOpen.value = status;
- if (options?.onChange)
- options.onChange(status);
- }
- });
- })
- })
-
- onUnmounted(() => {
- keyboardCore.offChangeVisibility();
- })
-
- const open = (target?: ViewRef) => {
- const viewTarget = unrefView(target!);
- const viewDefaultTarget = options?.defaultTarget ? unrefView(options?.defaultTarget!) : null;
- if (viewTarget) {
- keyboardCore.open(viewTarget);
- } else if (viewDefaultTarget) {
- keyboardCore.open(viewDefaultTarget);
- } else {
- console.log("Error. Need to define a view to apply focus.");
- }
- }
- return {
- isOpen: readonly(isOpen),
- open,
- close: keyboardCore.close,
- }
-}
-
diff --git a/packages/nativescript-vueuse/src/useRootLayout/index.ts b/packages/nativescript-vueuse/src/useRootLayout/index.ts
deleted file mode 100644
index 871e8ef..0000000
--- a/packages/nativescript-vueuse/src/useRootLayout/index.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { createNativeView, ref } from "nativescript-vue"
-import { RootLayoutOptions, ViewBase, getRootLayout } from "@nativescript/core"
-
-/**
- * Utility for the RootLayout view.
- *
- * @param component
- * @param options
- */
-export function useRootLayout(
- component: any,
- options?: { props?: any, rootLayoutOption?: RootLayoutOptions, onClose?: () => void },
-) {
- const isShow = ref(false);
- const node = createNativeView(component, options?.props);
- node.mount();
- const view = node.nativeView;
-
- view.on(ViewBase.unloadedEvent, () => {
- isShow.value = false;
- if (options?.onClose)
- options.onClose();
- });
-
- function show() {
- isShow.value = true;
- return getRootLayout().open(view, options?.rootLayoutOption);
- }
-
- function close() {
- getRootLayout().close(view);
- }
-
- return {
- show,
- close,
- isShow,
- view
- }
-}
-
diff --git a/packages/nativescript-vueuse/src/useScreenOrientation/index.ts b/packages/nativescript-vueuse/src/useScreenOrientation/index.ts
deleted file mode 100644
index a69bc0d..0000000
--- a/packages/nativescript-vueuse/src/useScreenOrientation/index.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { ref, readonly, onUnmounted } from "nativescript-vue"
-import { CoreTypes } from "@nativescript/core";
-import { Orientation } from "@vallemar/nativescript-orientation";
-
-
-/**
- * Reactive screen orientation and utilities to manage the orientation.
- *
- * @param target
- * @param options
- */
-export function useScreenOrientation(
- options?: { onChange?: (orientation: CoreTypes.DeviceOrientationType) => void },
-) {
- const orientationCore = new Orientation();
- const orientation = ref(orientationCore.getOrientation());
-
- let tryCount = 0;
- function tryOrientation() {
- if (orientation.value === CoreTypes.DeviceOrientation.unknown) {
- if (tryCount < 4) {
- setTimeout(() => {
- tryCount++;
- tryOrientation();
- }, 100);
- }
- } else {
- orientation.value = orientationCore.getOrientation();
- if (options?.onChange)
- options.onChange(orientation.value)
- }
- }
- if (orientation.value === CoreTypes.DeviceOrientation.unknown) tryOrientation();
-
- orientationCore.onChangedOrientation((value: {newValue: CoreTypes.DeviceOrientationType}) => {
- orientation.value = value.newValue;
- if (options?.onChange)
- options.onChange(orientation.value)
- })
-
- onUnmounted(() =>{
- orientationCore.offChangedOrientation();
- })
- return {
- orientation: readonly(orientation),
- setOrientation: orientationCore.setOrientation,
- enableRotation: orientationCore.enableRotation,
- disableRotation: orientationCore.disableRotation
- }
-}
diff --git a/packages/nativescript-vueuse/src/useStorage/index.md b/packages/nativescript-vueuse/src/useStorage/index.md
deleted file mode 100644
index d06c6f0..0000000
--- a/packages/nativescript-vueuse/src/useStorage/index.md
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# useStorage
-
-Storage tool for NativeScript.
-
-
-## Usage
-
-```ts
-import { useStorage } from '@vallemar/nativescript-vueuse'
-
-const storage = useStorage();
-storage.setObject("key", { foo: "bar" });
-```
-
-
-## Full methods
-
-```ts
-export declare const useStorage: () => {
- getObject: (key: string, defaultValue?: T | undefined) => T;
- setObject: (key: string, value: any) => void;
- getString: (key: string, defaultValue?: string) => string;
- setString: (key: string, value: string) => void;
- getNumber: (key: string, defaultValue?: number) => number;
- setNumber: (key: string, value: number) => void;
- getBoolean: (key: string, defaultValue?: boolean) => boolean;
- setBoolean: (key: string, value: boolean) => void;
- remove: (key: string) => void;
- clear: () => void;
-};
-
-```
\ No newline at end of file
diff --git a/packages/nativescript-vueuse/src/useStorage/index.ts b/packages/nativescript-vueuse/src/useStorage/index.ts
deleted file mode 100644
index 0138f34..0000000
--- a/packages/nativescript-vueuse/src/useStorage/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { ApplicationSettings } from "@nativescript/core";
-
- const storage = {
- getObject: (key: string, defaultValue?: T): T => {
- const value = storage.getString(key);
- return value ? JSON.parse(value) : defaultValue;
- },
- setObject: (key: string, value: any) => {
- storage.setString(key, JSON.stringify(value));
- },
- getString: (key: string, defaultValue?: string): string => {
- return ApplicationSettings.getString(key, defaultValue);
- },
- setString: (key: string, value: string) => {
- ApplicationSettings.setString(key, value);
- },
- getNumber: (key: string, defaultValue?: number) => {
- return ApplicationSettings.getNumber(key, defaultValue);
- },
- setNumber: (key: string, value: number) => {
- ApplicationSettings.setNumber(key, value);
- },
- getBoolean: (key: string, defaultValue?: boolean) => {
- return ApplicationSettings.getBoolean(key, defaultValue);
- },
- setBoolean: (key: string, value: boolean) => {
- ApplicationSettings.setBoolean(key, value);
- },
- remove: (key: string) => {
- ApplicationSettings.remove(key);
- },
- clear: () => {
- ApplicationSettings.clear();
- },
-};
-
-export const useStorage = () => storage
\ No newline at end of file
diff --git a/packages/vue/.eslintrc.json b/packages/vue/.eslintrc.json
new file mode 100644
index 0000000..53c06c8
--- /dev/null
+++ b/packages/vue/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*", "node_modules/**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/packages/vue/.vitepress/config.mts b/packages/vue/.vitepress/config.mts
new file mode 100644
index 0000000..f6c4597
--- /dev/null
+++ b/packages/vue/.vitepress/config.mts
@@ -0,0 +1,92 @@
+import { defineConfig } from 'vitepress';
+
+const logo = 'https://art.nativescript-vue.org/NativeScript-Vue-Green-White.svg';
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+ vite: {
+ define: {
+ BASE_BLOB_SOURCE: JSON.stringify('https://github.com/NativeScript-Use/NativeScript-Use/blob/main/packages/vue/src/'),
+ STACKBLITZ_VIEW: JSON.stringify('https://stackblitz.com/edit/nativescrip-use-vue/?file=src/views/')
+ }
+ },
+ head: [
+ /* ['link', { rel: "apple-touch-icon", sizes: "180x180", href: "https://nativescript-vue.org/apple-touch-icon.png"}],
+ ['link', { rel: "icon", type: "image/png", sizes: "32x32", href: "https://nativescript-vue.org/favicon-32x32.png"}],
+ ['link', { rel: "icon", type: "image/png", sizes: "16x16", href: "https://nativescript-vue.org/favicon-16x16.png"}],
+ */
+ ['link', { rel: 'icon', type: 'image/svg', sizes: '32x32', href: logo }],
+ [
+ 'script',
+ {
+ async: 'false',
+ src: 'https://unpkg.com/@vueuse/core',
+ },
+ ],
+ [
+ 'script',
+ {
+ async: 'true',
+ src: 'https://www.googletagmanager.com/gtag/js?id=G-RV37C0FX94',
+ },
+ ],
+ ['script', {}, "window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-RV37C0FX94');"],
+ ],
+ appearance: "dark",
+ title: '@NativeScript-Use/Vue',
+ description: 'Collection of NativeScript-Vue3 Composition Utilities',
+ themeConfig: {
+ logo,
+ // https://vitepress.dev/reference/default-theme-config
+ nav: [
+ { text: 'Home', link: '/' },
+ { text: 'Get Started', link: '/started' },
+ { text: 'Functions', link: '/src/unrefView/index.md' },
+ { text: 'Playground', link: 'https://stackblitz.com/edit/nativescrip-use-vue?file=src%2Fapp.ts' },
+ ],
+
+ sidebar: [
+ {
+ text: 'Guide',
+ items: [{ text: 'Get Started', link: '/started' }],
+ },
+ {
+ text: 'Functions',
+ items: [
+ { text: 'refView', link: '/src/refView/index.md' },
+ { text: 'unrefView', link: '/src/unrefView/index.md' },
+ { text: 'useBreakpoints', link: '/src/useBreakpoints/index.md' },
+ { text: 'useClipboard', link: '/src/useClipboard/index.md' },
+ { text: 'useColorMode', link: '/src/useColorMode/index.md' },
+ { text: 'useColorPalette', link: '/src/useColorPalette/index.md' },
+ { text: 'useContentElementSize', link: '/src/useContentElementSize/index.md' },
+ { text: 'useDark', link: '/src/useDark/index.md' },
+ { text: 'useElementSize', link: '/src/useElementSize/index.md' },
+ { text: 'useFadeElement', link: '/src/useFadeElement/index.md' },
+ { text: 'useEventListener', link: '/src/useEventListener/index.md' },
+ { text: 'useIntersectionObserver', link: '/src/useIntersectionObserver/index.md' },
+ { text: 'useKeyboard', link: '/src/useKeyboard/index.md' },
+ { text: 'useMediaQuery', link: '/src/useMediaQuery/index.md' },
+ { text: 'useRootLayout', link: '/src/useRootLayout/index.md' },
+ { text: 'useScreenOrientation', link: '/src/useScreenOrientation/index.md' },
+ { text: 'useStorage', link: '/src/useStorage/index.md' },
+ { text: 'useSyncObservableArray', link: '/src/useSyncObservableArray/index.md' },
+ { text: 'useWorker', link: '/src/useWorker/index.md' },
+ ],
+ },
+ {
+ text: 'Global hooks',
+ items: [{ text: 'onApplicationMounted', link: '/src/onApplicationMounted/index.md' }],
+ },
+ ],
+
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/NativeScript-Use/NativeScript-Use' },
+ { icon: 'discord', link: 'https://discord.com/invite/RgmpGky9GR' },
+ //{ icon: { svg: 'https://upload.wikimedia.org/wikipedia/commons/d/db/Npm-logo.svg'}, link: 'https://www.npmjs.com/package/@vallemar/nativescript-vueuse' }
+ ],
+ search: {
+ provider: 'local',
+ },
+
+ },
+});
diff --git a/packages/vue/.vitepress/theme/components/Home.vue b/packages/vue/.vitepress/theme/components/Home.vue
new file mode 100644
index 0000000..2c2f6aa
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/Home.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/components/HomeContributors.vue b/packages/vue/.vitepress/theme/components/HomeContributors.vue
new file mode 100644
index 0000000..69fdf53
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/HomeContributors.vue
@@ -0,0 +1,36 @@
+
+
+
Contributors
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/vue/.vitepress/theme/components/Preview.vue b/packages/vue/.vitepress/theme/components/Preview.vue
new file mode 100644
index 0000000..91d92c7
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/Preview.vue
@@ -0,0 +1,52 @@
+
+
+
+
Try with
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/vue/.vitepress/theme/components/Source.vue b/packages/vue/.vitepress/theme/components/Source.vue
new file mode 100644
index 0000000..36f94d4
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/Source.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/components/Sponsor.vue b/packages/vue/.vitepress/theme/components/Sponsor.vue
new file mode 100644
index 0000000..f8af5bb
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/Sponsor.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/components/Sponsors.vue b/packages/vue/.vitepress/theme/components/Sponsors.vue
new file mode 100644
index 0000000..d011200
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/Sponsors.vue
@@ -0,0 +1,21 @@
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/components/YoutubeVideo.vue b/packages/vue/.vitepress/theme/components/YoutubeVideo.vue
new file mode 100644
index 0000000..04882ae
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/YoutubeVideo.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/components/balls.vue b/packages/vue/.vitepress/theme/components/balls.vue
new file mode 100644
index 0000000..1c584eb
--- /dev/null
+++ b/packages/vue/.vitepress/theme/components/balls.vue
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/vue/.vitepress/theme/index.ts b/packages/vue/.vitepress/theme/index.ts
new file mode 100644
index 0000000..6600998
--- /dev/null
+++ b/packages/vue/.vitepress/theme/index.ts
@@ -0,0 +1,16 @@
+// https://vitepress.dev/guide/custom-theme
+import { h } from 'vue';
+import Theme from 'vitepress/theme';
+import './style.css';
+
+export default {
+ ...Theme,
+ Layout: () => {
+ return h(Theme.Layout, null, {
+ // https://vitepress.dev/guide/extending-default-theme#layout-slots
+ });
+ },
+ enhanceApp({ app, router, siteData }) {
+ // ...
+ },
+};
diff --git a/packages/vue/.vitepress/theme/style.css b/packages/vue/.vitepress/theme/style.css
new file mode 100644
index 0000000..224c09c
--- /dev/null
+++ b/packages/vue/.vitepress/theme/style.css
@@ -0,0 +1,100 @@
+/**
+ * Customize default theme styling by overriding CSS variables:
+ * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
+ */
+
+/**
+ * Colors
+ * -------------------------------------------------------------------------- */
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ --vp-c-brand: #21cd80;
+ --vp-c-brand-light: rgba(40, 230, 145, 0.991);
+ --vp-c-brand-lighter: #9499ff;
+ --vp-c-brand-lightest: #bcc0ff;
+ --vp-c-brand-dark: #535bf2;
+ --vp-c-brand-darker: #454ce1;
+ --vp-c-brand-dimm: rgba(100, 108, 255, 0.08);
+}
+
+/**
+ * Component: Button
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-button-brand-border: var(--vp-c-brand-light);
+ --vp-button-brand-text: var(--vp-c-white);
+ --vp-button-brand-bg: var(--vp-c-brand);
+ --vp-button-brand-hover-border: var(--vp-c-brand-light);
+ --vp-button-brand-hover-text: var(--vp-c-white);
+ --vp-button-brand-hover-bg: var(--vp-c-brand-light);
+ --vp-button-brand-active-border: var(--vp-c-brand-light);
+ --vp-button-brand-active-text: var(--vp-c-white);
+ --vp-button-brand-active-bg: var(--vp-button-brand-bg);
+}
+
+/**
+ * Component: Home
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: -webkit-linear-gradient(120deg,
+ rgb(40, 230, 145),
+ #65adf1 50%);
+
+
+ --vp-home-hero-image-background-image: linear-gradient(-45deg,
+ rgba(65, 184, 131, 0.5) 30%, rgb(101, 173, 241));
+ --vp-home-hero-image-filter: blur(40px);
+}
+
+@media (min-width: 640px) {
+ :root {
+ --vp-home-hero-image-filter: blur(56px);
+ }
+}
+
+@media (min-width: 960px) {
+ :root {
+ --vp-home-hero-image-filter: blur(72px);
+ }
+}
+
+/**
+ * Component: Custom Block
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-custom-block-tip-border: var(--vp-c-brand);
+ --vp-custom-block-tip-text: var(--vp-c-brand-darker);
+ --vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
+
+ --vp-c-brand-1: var(--vp-c-brand);
+ --vp-c-brand-2: #65adf1;
+/* --vp-font-family-base: 'Uber Move Text', sans-serif; */
+}
+
+.dark {
+ --vp-custom-block-tip-border: var(--vp-c-brand);
+ --vp-custom-block-tip-text: var(--vp-c-brand-lightest);
+ --vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
+ --vp-c-brand: rgba(40, 230, 145, 0.666);
+}
+
+/**
+ * Component: Algolia
+ * -------------------------------------------------------------------------- */
+
+.DocSearch {
+ --docsearch-primary-color: var(--vp-c-brand) !important;
+}
+
+
+h3{
+ font-size: 24px;
+ font-weight: bold;
+}
\ No newline at end of file
diff --git a/packages/vue/README.md b/packages/vue/README.md
new file mode 100644
index 0000000..51173e3
--- /dev/null
+++ b/packages/vue/README.md
@@ -0,0 +1,10 @@
+# @nativescript-use/vue
+
+```javascript
+npm install @nativescript-use/vue
+```
+
+[Documentation (Vue3)](https://nativescriptuse-vue.netlify.app/)
+
+
+Apache License Version 2.0
diff --git a/packages/vue/index.d.ts b/packages/vue/index.d.ts
new file mode 100644
index 0000000..4d416c1
--- /dev/null
+++ b/packages/vue/index.d.ts
@@ -0,0 +1,24 @@
+/* Functions */
+export * from './src/unrefView';
+export * from './src/refView';
+export * from './src/useBreakpoints';
+export * from './src/useClipboard';
+export * from './src/useColorMode';
+export * from './src/useColorPalette';
+export * from './src/useContentElementSize';
+export * from './src/useDark';
+export * from './src/useElementSize';
+export * from './src/useFadeElement';
+export * from './src/useEventListener';
+export * from './src/useIntersectionObserver';
+export * from './src/useKeyboard';
+export * from './src/useMediaQuery';
+export * from './src/useRootLayout';
+export * from './src/useScreenOrientation';
+export * from './src/useStorage';
+export * from './src/useSyncObservableArray';
+export * from './src/useWorker';
+export * from './src/types';
+
+/* Global hooks */
+export * from './src/onApplicationMounted';
diff --git a/packages/vue/index.md b/packages/vue/index.md
new file mode 100644
index 0000000..eec105c
--- /dev/null
+++ b/packages/vue/index.md
@@ -0,0 +1,33 @@
+---
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ name: "@NativeScrip-Use/Vue"
+ text: "Collection of NativeScript-Vue3 Composition Utilities"
+ image: https://art.nativescript-vue.org/misc/phone.svg
+ actions:
+ - theme: brand
+ text: Get Started
+ link: /started
+ - theme: alt
+ text: Functions
+ link: /src/unrefView/index.md
+
+---
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/vue/index.ts b/packages/vue/index.ts
new file mode 100644
index 0000000..4d416c1
--- /dev/null
+++ b/packages/vue/index.ts
@@ -0,0 +1,24 @@
+/* Functions */
+export * from './src/unrefView';
+export * from './src/refView';
+export * from './src/useBreakpoints';
+export * from './src/useClipboard';
+export * from './src/useColorMode';
+export * from './src/useColorPalette';
+export * from './src/useContentElementSize';
+export * from './src/useDark';
+export * from './src/useElementSize';
+export * from './src/useFadeElement';
+export * from './src/useEventListener';
+export * from './src/useIntersectionObserver';
+export * from './src/useKeyboard';
+export * from './src/useMediaQuery';
+export * from './src/useRootLayout';
+export * from './src/useScreenOrientation';
+export * from './src/useStorage';
+export * from './src/useSyncObservableArray';
+export * from './src/useWorker';
+export * from './src/types';
+
+/* Global hooks */
+export * from './src/onApplicationMounted';
diff --git a/packages/vue/nativescript.webpack.ts b/packages/vue/nativescript.webpack.ts
new file mode 100644
index 0000000..d21ca62
--- /dev/null
+++ b/packages/vue/nativescript.webpack.ts
@@ -0,0 +1,7 @@
+//@ts-ignore
+const webpack = require('@nativescript/webpack');
+
+module.exports = (env) => {
+ const wepackTask = require('@nativescript-use/nativescript-task/nativescript.webpack.js');
+ wepackTask(webpack);
+};
diff --git a/packages/vue/package.json b/packages/vue/package.json
new file mode 100644
index 0000000..d74f5b8
--- /dev/null
+++ b/packages/vue/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "@nativescript-use/vue",
+ "version": "0.0.51",
+ "description": "Add a plugin description",
+ "main": "index",
+ "typings": "index.d.ts",
+ "nativescript": {
+ "platforms": {
+ "ios": "6.0.0",
+ "android": "6.0.0"
+ }
+ },
+ "scripts": {},
+ "dependencies": {
+ "@nativescript-use/nativescript-clipboard": "0.0.3",
+ "@nativescript-use/nativescript-intersection-observer": "0.0.1",
+ "@nativescript-use/nativescript-keyboard": "0.0.1",
+ "@nativescript-use/nativescript-localstorage": "0.0.1",
+ "@nativescript-use/nativescript-media-query": "0.0.4",
+ "@nativescript-use/nativescript-orientation": "0.0.3",
+ "@nativescript-use/nativescript-task": "^0.0.11",
+ "@vueuse/core": "^12.5.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
+ },
+ "keywords": [
+ "NativeScript",
+ "JavaScript",
+ "TypeScript",
+ "iOS",
+ "Android"
+ ],
+ "author": {
+ "name": "Juan de Dios Matínez Vallejo",
+ "email": "oss@nativescript.org"
+ },
+ "bugs": {
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
+ },
+ "license": "Apache-2.0",
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use",
+ "readmeFilename": "README.md",
+ "bootstrapper": "@nativescript/plugin-seed"
+}
diff --git a/packages/vue/project.json b/packages/vue/project.json
new file mode 100644
index 0000000..1b58fb4
--- /dev/null
+++ b/packages/vue/project.json
@@ -0,0 +1,66 @@
+{
+ "name": "vue",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "library",
+ "sourceRoot": "packages/vue",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "options": {
+ "outputPath": "dist/packages/vue",
+ "tsConfig": "packages/vue/tsconfig.json",
+ "packageJson": "packages/vue/package.json",
+ "main": "packages/vue/index.d.ts",
+ "generatePackageJson": false,
+ "assets": [
+ "packages/vue/*.md",
+ "packages/vue/index.d.ts",
+ "LICENSE",
+ {
+ "glob": "**/*",
+ "input": "packages/vue/platforms/",
+ "output": "./platforms/"
+ }
+ ],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ }
+ ]
+ }
+ },
+ "build.all": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["node tools/scripts/build-finish.ts vue"],
+ "parallel": false
+ },
+ "outputs": ["dist/packages/vue"],
+ "dependsOn": [
+ {
+ "target": "build.all",
+ "projects": "dependencies"
+ },
+ {
+ "target": "build",
+ "projects": "self"
+ }
+ ]
+ },
+ "focus": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["nx g @nativescript/plugin-tools:focus-packages vue"],
+ "parallel": false
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": ["packages/vue/**/*.ts"]
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/packages/vue/references.d.ts b/packages/vue/references.d.ts
new file mode 100644
index 0000000..22bac92
--- /dev/null
+++ b/packages/vue/references.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/vue/src/constant.ts b/packages/vue/src/constant.ts
new file mode 100644
index 0000000..f6df560
--- /dev/null
+++ b/packages/vue/src/constant.ts
@@ -0,0 +1 @@
+export const LOG_PREFIX = '[@nativescript-use/vue]: ';
diff --git a/packages/vue/src/globalState.ts b/packages/vue/src/globalState.ts
new file mode 100644
index 0000000..282cdd4
--- /dev/null
+++ b/packages/vue/src/globalState.ts
@@ -0,0 +1,16 @@
+import { effectScope } from 'nativescript-vue';
+
+export type AnyFn = (...args: any[]) => any;
+export function createGlobalState(stateFactory: Fn): Fn {
+ let initialized = false;
+ let state: any;
+ const scope = effectScope(true);
+
+ return ((...args: any[]) => {
+ if (!initialized) {
+ state = scope.run(() => stateFactory(...args))!;
+ initialized = true;
+ }
+ return state;
+ }) as Fn;
+}
diff --git a/packages/nativescript-vueuse/src/onApplicationMounted/index.md b/packages/vue/src/onApplicationMounted/index.md
similarity index 88%
rename from packages/nativescript-vueuse/src/onApplicationMounted/index.md
rename to packages/vue/src/onApplicationMounted/index.md
index b92d2c9..57db91f 100644
--- a/packages/nativescript-vueuse/src/onApplicationMounted/index.md
+++ b/packages/vue/src/onApplicationMounted/index.md
@@ -1,8 +1,10 @@
+
# onApplicationMounted
Secure hook to access the native main view.
-
There are times when we want to access the main view of the application or access the native side when starting the application or we want to have global functions that can be used when starting the application or at another point. `onApplicationMounted` ensures that the application is mounted, if it hasn't been mounted yet it will wait until you do and if it is mounted it will execute your code right away.
@@ -23,7 +25,7 @@ const frame = Frame.topmost(); // 💀 will be undefined
createApp(Home).start();
```
-
+
## Solution
@@ -31,7 +33,7 @@ createApp(Home).start();
// app.ts / main.ts
import { createApp } from 'nativescript-vue';
import { Application, Utils } from "@nativescript/core";
-import { onApplicationMounted } from '@vallemar/nativescript-vueuse';
+import { onApplicationMounted } from '@nativescript-use/vue';
onApplicationMounted(() => { // 👏 fixed with this
if(global.isAndroid){
@@ -45,9 +47,10 @@ onApplicationMounted(() => { // 👏 fixed with this
createApp(Home).start();
```
-
+## Source
+
## Type declaration
```ts
diff --git a/packages/vue/src/onApplicationMounted/index.ts b/packages/vue/src/onApplicationMounted/index.ts
new file mode 100644
index 0000000..f026e0b
--- /dev/null
+++ b/packages/vue/src/onApplicationMounted/index.ts
@@ -0,0 +1,14 @@
+import { Application, Frame } from '@nativescript/core';
+
+export const onApplicationMounted = (callback: () => void, immediateCallback?: () => void) => {
+ if (Frame.topmost()) {
+ immediateCallback ? immediateCallback() : null;
+ callback();
+ } else {
+ const run = () => {
+ setTimeout(callback, 0);
+ Application.off('launch', run);
+ };
+ Application.on('launch', run);
+ }
+};
diff --git a/packages/vue/src/refView/index.md b/packages/vue/src/refView/index.md
new file mode 100644
index 0000000..9bdb660
--- /dev/null
+++ b/packages/vue/src/refView/index.md
@@ -0,0 +1,47 @@
+
+
+# refView
+
+Utility typed Ref of NativeScript View.
+
+## Usage
+
+```vue
+
+
+
+
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import type { View } from '@nativescript/core';
+import { Ref } from 'nativescript-vue';
+
+/**
+ * Utility. Typed Ref of View.
+ */
+export declare function refView(): Ref;
+```
+
diff --git a/packages/vue/src/refView/index.ts b/packages/vue/src/refView/index.ts
new file mode 100644
index 0000000..9115e96
--- /dev/null
+++ b/packages/vue/src/refView/index.ts
@@ -0,0 +1,32 @@
+import type { View } from '@nativescript/core';
+import { Ref, customRef } from 'nativescript-vue';
+import { unrefView } from '../unrefView';
+
+/**
+ * Utility. Typed Ref of View.
+ */
+export function refView(): Ref {
+ return customRef((track, trigger) => {
+ let view: View | undefined = undefined;
+ return {
+ get() {
+ track();
+ return view;
+ },
+ set(newValue: any) {
+ view = unrefView(newValue);
+ watchPushIfIsArray(view);
+ trigger();
+ },
+ };
+ });
+}
+
+function watchPushIfIsArray(view: any) {
+ if (view && Array.isArray(view)) {
+ view.push = function (data) {
+ const newItem = unrefView(data);
+ return Array.prototype.push.apply(this, Array.isArray(newItem) ? newItem : [newItem]);
+ };
+ }
+}
diff --git a/packages/vue/src/types.ts b/packages/vue/src/types.ts
new file mode 100644
index 0000000..28ca8b1
--- /dev/null
+++ b/packages/vue/src/types.ts
@@ -0,0 +1,11 @@
+import { View } from '@nativescript/core';
+import { Ref, ShallowRef } from 'nativescript-vue';
+
+type NativeElement = {
+ nativeView?: T;
+ $el?: {
+ nativeView: T;
+ };
+};
+
+export type ViewRef = T | Ref> | Readonly>>;
diff --git a/packages/vue/src/unrefView/index.md b/packages/vue/src/unrefView/index.md
new file mode 100644
index 0000000..3310127
--- /dev/null
+++ b/packages/vue/src/unrefView/index.md
@@ -0,0 +1,43 @@
+
+
+# unrefView
+
+Extract a NativeScript view from a Ref
+
+## Usage
+
+```vue
+
+
+
+
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { View } from "@nativescript/core";
+import { ViewRef } from "@nativescript-use/vue";
+/**
+ * Utility. Get View from Ref.
+ *
+ * @param target
+ */
+export declare function unrefView(target: T | ViewRef): T | undefined;
+```
+
diff --git a/packages/vue/src/unrefView/index.ts b/packages/vue/src/unrefView/index.ts
new file mode 100644
index 0000000..9e30380
--- /dev/null
+++ b/packages/vue/src/unrefView/index.ts
@@ -0,0 +1,22 @@
+import { View } from '@nativescript/core';
+import { ViewRef } from '../types';
+
+/**
+ * Utility. Get View from Ref.
+ *
+ * @param target
+ */
+export function unrefView(ref: T | any /* ViewRef */): T | undefined {
+ if (ref?.value instanceof View) return ref?.value;
+ if (ref instanceof View) return ref as T;
+ if (ref?.value?.nativeView) return ref?.value.nativeView;
+ if (ref?.value?.$el?.nativeView) return ref?.value?.$el?.nativeView;
+ if (ref?.nativeView) return ref?.nativeView;
+ if (ref?.$el?.nativeView) return ref?.$el?.nativeView;
+ // @ts-ignore
+ if (Array.isArray(ref?.value)) return (ref?.value as any[]).map((view) => unrefView(view)) as T[];
+ // @ts-ignore
+ if (Array.isArray(ref)) return (ref as any[]).map((view) => unrefView(view)) as T[];
+
+ return undefined;
+}
diff --git a/packages/vue/src/useBreakpoints/index.md b/packages/vue/src/useBreakpoints/index.md
new file mode 100644
index 0000000..7a77887
--- /dev/null
+++ b/packages/vue/src/useBreakpoints/index.md
@@ -0,0 +1,76 @@
+
+
+# useBreakpoints
+
+Reactive screen breakpoints.
+
+## Usage
+
+```vue
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { Ref, ComputedRef } from "nativescript-vue";
+export declare type Breakpoints = Record;
+/**
+ * Reactive screen breakpoints.
+ *
+ * @param breakpoints
+ */
+export declare function useBreakpoints(breakpoints: Breakpoints): Record> & {
+ greater(k: K): Ref;
+ greaterOrEqual: (k: K) => Ref;
+ smaller(k: K): Ref;
+ smallerOrEqual(k: K): Ref;
+ between(a: K, b: K): Ref;
+ isGreater(k: K): Ref;
+ isGreaterOrEqual(k: K): Ref;
+ isSmaller(k: K): Ref;
+ isSmallerOrEqual(k: K): Ref;
+ isInBetween(a: K, b: K): Ref;
+ current(): ComputedRef;
+};
+
+```
+
+## Core dependency
+[@nativescript-use/nativescript-media-query](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-media-query)
\ No newline at end of file
diff --git a/packages/vue/src/useBreakpoints/index.ts b/packages/vue/src/useBreakpoints/index.ts
new file mode 100644
index 0000000..cf0ebfd
--- /dev/null
+++ b/packages/vue/src/useBreakpoints/index.ts
@@ -0,0 +1,66 @@
+import { Ref, computed } from 'nativescript-vue';
+import { useMediaQuery } from '../useMediaQuery';
+
+export type Breakpoints = Record;
+
+/**
+ * Reactive screen breakpoints.
+ *
+ * @param breakpoints
+ */
+export function useBreakpoints(breakpoints: Breakpoints) {
+ function getValue(k: K, d?: number) {
+ let v = breakpoints[k];
+ return v;
+ }
+
+ const greaterOrEqual = (k: K) => {
+ return useMediaQuery(`(min-width: ${getValue(k)})`);
+ };
+
+ const shortcutMethods = Object.keys(breakpoints).reduce((shortcuts, k) => {
+ Object.defineProperty(shortcuts, k, {
+ get: () => greaterOrEqual(k as K),
+ enumerable: true,
+ configurable: true,
+ });
+ return shortcuts;
+ }, {} as Record>);
+
+ return Object.assign(shortcutMethods, {
+ greater(k: K) {
+ return useMediaQuery(`(min-width: ${getValue(k, 0.1)})`);
+ },
+ greaterOrEqual,
+ smaller(k: K) {
+ return useMediaQuery(`(max-width: ${getValue(k, -0.1)})`);
+ },
+ smallerOrEqual(k: K) {
+ return useMediaQuery(`(max-width: ${getValue(k)})`);
+ },
+ between(a: K, b: K) {
+ return useMediaQuery(`(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`);
+ },
+ isGreater(k: K) {
+ return useMediaQuery(`(min-width: ${getValue(k, 0.1)})`);
+ },
+ isGreaterOrEqual(k: K) {
+ return useMediaQuery(`(min-width: ${getValue(k)})`);
+ },
+ isSmaller(k: K) {
+ return useMediaQuery(`(max-width: ${getValue(k, -0.1)})`);
+ },
+ isSmallerOrEqual(k: K) {
+ return useMediaQuery(`(max-width: ${getValue(k)})`);
+ },
+ isInBetween(a: K, b: K) {
+ return useMediaQuery(`(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`);
+ },
+ current() {
+ const points = Object.keys(breakpoints).map((i) => [i, greaterOrEqual(i as K)] as const);
+ return computed(() => {
+ return points.filter(([, v]) => v.value).map(([k]) => k);
+ });
+ },
+ });
+}
diff --git a/packages/nativescript-vueuse/src/useClipboard/index.md b/packages/vue/src/useClipboard/index.md
similarity index 78%
rename from packages/nativescript-vueuse/src/useClipboard/index.md
rename to packages/vue/src/useClipboard/index.md
index 1764731..5147b4b 100644
--- a/packages/nativescript-vueuse/src/useClipboard/index.md
+++ b/packages/vue/src/useClipboard/index.md
@@ -1,3 +1,6 @@
+
# useClipboard
@@ -29,12 +32,14 @@ const {
```
-
+
::: warning
By default clipboard synchronization is disabled, which means that if the user copies something within your application this function will not detect it. To enable synchronization and for the reactive variable `text` to be synchronized with the clipboard, you must enable `{ sync: true }`.
:::
+## Source
+
## Type declaration
```ts
@@ -52,3 +57,6 @@ export declare function useClipboard(options?: {
read: () => string;
};
```
+
+## Core dependency
+[@nativescript-use/nativescript-clipboard](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-clipboard)
\ No newline at end of file
diff --git a/packages/vue/src/useClipboard/index.ts b/packages/vue/src/useClipboard/index.ts
new file mode 100644
index 0000000..514aab4
--- /dev/null
+++ b/packages/vue/src/useClipboard/index.ts
@@ -0,0 +1,54 @@
+import { onUnmounted, ref } from 'nativescript-vue';
+import { Clipboard } from '@nativescript-use/nativescript-clipboard';
+import { onApplicationMounted } from '../onApplicationMounted';
+
+/**
+ * Reactive Clipboard API. Provides the ability to respond to clipboard commands.
+ *
+ */
+export function useClipboard(options?: { sync?: boolean }) {
+ const { sync = false } = options ?? {};
+
+ let clipboard: Clipboard | undefined;
+
+ const copied = ref(false);
+ const text = ref('');
+
+ const copy = (text: string) => {
+ copied.value = clipboard?.copy(text) ?? false;
+ };
+
+ const read = () => {
+ text.value = clipboard?.read() ?? '';
+ return text.value;
+ };
+
+ onApplicationMounted(
+ () => {
+ if (!clipboard) clipboard = new Clipboard();
+ if (sync) {
+ text.value = clipboard.read();
+ clipboard.onCopy((copyText) => {
+ text.value = copyText;
+ });
+ }
+ },
+ () => {
+ clipboard = new Clipboard();
+ if (sync) {
+ text.value = clipboard.read();
+ }
+ }
+ );
+
+ onUnmounted(() => {
+ clipboard?.offCopy();
+ });
+
+ return {
+ text,
+ copied,
+ copy,
+ read,
+ };
+}
diff --git a/packages/nativescript-vueuse/src/useColorMode/index.md b/packages/vue/src/useColorMode/index.md
similarity index 80%
rename from packages/nativescript-vueuse/src/useColorMode/index.md
rename to packages/vue/src/useColorMode/index.md
index 18f6514..2819ec5 100644
--- a/packages/nativescript-vueuse/src/useColorMode/index.md
+++ b/packages/vue/src/useColorMode/index.md
@@ -1,11 +1,28 @@
+
# useColorMode
Reactive color mode (dark / light / customs) with auto data persistence.
-
## Usage
-### Initialize
+### Basic Initialize
+To use only light/dark themes you can initialize with the basic setting `useColorMode`
+
+```js
+// app.ts / main.ts
+
+import { createApp } from 'nativescript-vue';
+import { useColorMode } from "@nativescript-use/vue";
+
+/* Init ColorMode */
+useColorMode({ initialValue: 'auto' })
+
+createApp(Home).start();
+```
+
+### Advanced initializer
To add custom modes other than `light/dark` you need to initialize in the input file to your application the custom modes you want to apply.
If you only want to use the `light/dark` modes this step is not necessary.
@@ -13,7 +30,7 @@ If you only want to use the `light/dark` modes this step is not necessary.
// app.ts / main.ts
import { createApp } from 'nativescript-vue';
-import { useColorMode } from "@vallemar/nativescript-vueuse";
+import { useColorMode } from "@nativescript-use/vue";
/* Init ColorMode */
const { system, schema, theme, modes } = useColorMode({
@@ -23,25 +40,21 @@ const { system, schema, theme, modes } = useColorMode({
'cafe',
],
initialValue: 'auto',
- storageKey: 'nativevueuse-color-scheme',
onChanged: (theme: 'dark' | 'light' | 'dim' | 'cafe') => {
}
})
createApp(Home).start();
```
-
+
### Use in your application
```ts
import { computed } from 'nativescript-vue'
-import { useColorMode } from '@vallemar/nativescript-vueuse'
+import { useColorMode } from '@nativescript-use/vue'
-const { system, schema, theme, modes } = useColorMode({
- onChanged: (theme: 'dark' | 'light' | 'dim' | 'cafe') => {
- }
-})
+const { system, schema, theme, modes } = useColorMode();
schema // Ref<'dark' | 'light' | 'dim' | 'cafe' | 'auto'> 👈 use this for change theme
system // Readonly[>
@@ -49,7 +62,11 @@ theme // Readonly][>;
modes // Readonly][>;
function changeTheme(){
- schema.value = 'cafe' // change to cafe mode
+ schema.value = 'cafe'; // change to cafe mode
+}
+
+function changeToDeviceTheme(){
+ schema.value = 'auto';
}
```
@@ -108,7 +125,9 @@ Then you can do the following
```html
]
```
-
+
+## Source
+
## Type declaration
diff --git a/packages/vue/src/useColorMode/index.ts b/packages/vue/src/useColorMode/index.ts
new file mode 100644
index 0000000..89080b8
--- /dev/null
+++ b/packages/vue/src/useColorMode/index.ts
@@ -0,0 +1,134 @@
+import { Application, ApplicationSettings, CSSUtils, Frame } from '@nativescript/core';
+import { computed, getCurrentInstance, onUnmounted, readonly, ref, Ref, watch } from 'nativescript-vue';
+import { createGlobalState } from '../globalState';
+import { getSystemTheme } from './util';
+import removeSystemCssClass = CSSUtils.removeSystemCssClass;
+
+export type BasicColorMode = 'light' | 'dark';
+export type BasicColorSchema = BasicColorMode | 'auto';
+export interface UseColorModeOptions {
+ /**
+ * The initial color mode
+ *
+ * @default 'auto'
+ */
+ initialValue?: T | BasicColorSchema;
+
+ /**
+ * Prefix when adding value to the attribute
+ */
+ modes?: T[] | BasicColorSchema[];
+
+ /**
+ * A custom handler for handle the updates.
+ * When specified, the default behavior will be overridden.
+ *
+ * @default undefined
+ */
+ onChanged?: (mode: T | BasicColorMode) => void;
+
+ /**
+ * Key to persist the data into ApplicationSettings.
+ *
+ * Pass `null` to disable persistence
+ *
+ * @default 'nativevueuse-color-scheme'
+ */
+ storageKey?: string | null;
+}
+
+const useGlobalState = createGlobalState((storageKey: string, initialValue: string, themes: string[]) => {
+ const system = ref(getSystemTheme());
+ const schema = ref(ApplicationSettings.getString(storageKey!, initialValue.toString())) as Ref;
+ const modes = ref(themes);
+ return { system, schema, modes };
+});
+
+export function useColorMode(options: UseColorModeOptions = {}) {
+ const { initialValue = 'auto', storageKey = 'nativevueuse-color-scheme' } = options;
+
+ const { system, schema, modes } = useGlobalState(storageKey!, initialValue, ['auto', 'light', 'dark', ...(options.modes ?? [])]);
+
+ const theme = computed(() => (schema.value === 'auto' ? system.value : schema.value));
+ let internalSchema = schema.value;
+
+ Application.on('displayed', () => {
+ processTheme();
+ });
+ Application.on('systemAppearanceChanged', () => {
+ processTheme();
+ });
+
+ if (getCurrentInstance()) {
+ onUnmounted(() => {
+ Application.off('displayed', processTheme);
+ Application.off('systemAppearanceChanged', processTheme);
+ });
+ }
+
+ function processTheme() {
+ system.value = getSystemTheme();
+ if (schema.value === 'auto') {
+ applyTheme(system.value);
+ } else {
+ applyTheme(schema.value);
+ }
+ }
+
+ function applyTheme(themeToApply: T | BasicColorSchema) {
+ const rootView = Application.getRootView();
+ if (rootView && !rootView.className?.includes(getClassFromTheme(themeToApply))) {
+ schema.value = themeToApply;
+ const rootViewClass = new Set();
+ (Array.from(rootView.cssClasses).join(' ') ?? ' ').split(/\s+/).forEach((v) => v && rootViewClass.add(v));
+
+ modes.value.forEach((theme) => {
+ removeSystemCssClass(getClassFromTheme(theme));
+ rootViewClass.delete(getClassFromTheme(theme));
+ });
+
+ let applyTheme = themeToApply;
+ if (themeToApply.toLocaleLowerCase().trim() === 'auto') {
+ applyTheme = getSystemTheme();
+ Application.setAutoSystemAppearanceChanged(true);
+ Application.systemAppearanceChanged(rootView, getSystemTheme()!);
+ } else {
+ Application.setAutoSystemAppearanceChanged(false);
+ }
+ const classToApply = getClassFromTheme(applyTheme);
+ rootViewClass.add(classToApply);
+ CSSUtils.pushToSystemCssClasses(classToApply);
+ rootView.className = Array.from(rootViewClass).join(' ');
+ const frame = Frame.topmost();
+ frame?.backStack.forEach((backStack) => backStack?.resolvedPage?._onCssStateChange());
+ rootView._getRootModalViews()?.forEach((view) => {
+ view?._onCssStateChange();
+ });
+ ApplicationSettings.setString(storageKey!, themeToApply);
+
+ console.log('Apply: ' + classToApply);
+ }
+
+ if (rootView && schema.value !== internalSchema) {
+ internalSchema = schema.value;
+ if (options.onChanged) {
+ options.onChanged(theme.value);
+ }
+ }
+ }
+
+ watch(schema, () => {
+ applyTheme(schema.value);
+ });
+
+ processTheme();
+
+ return {
+ schema,
+ system: readonly(system),
+ theme: readonly(theme),
+ modes: readonly(modes),
+ };
+}
+
+const getClassFromTheme = (theme: string) => CSSUtils.CLASS_PREFIX + theme.toLocaleLowerCase().trim();
diff --git a/packages/vue/src/useColorMode/util.android.ts b/packages/vue/src/useColorMode/util.android.ts
new file mode 100644
index 0000000..e0c8c47
--- /dev/null
+++ b/packages/vue/src/useColorMode/util.android.ts
@@ -0,0 +1,14 @@
+import { Utils } from '@nativescript/core';
+
+export function getSystemTheme() {
+ const nightModeFlags = Utils.android.getApplicationContext().getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK;
+ switch (nightModeFlags) {
+ case android.content.res.Configuration.UI_MODE_NIGHT_YES:
+ return 'dark';
+ case android.content.res.Configuration.UI_MODE_NIGHT_NO:
+ return 'light';
+ default:
+ return 'light';
+ //case android.content.res.Configuration.UI_MODE_NIGHT_UNDEFINED:
+ }
+}
diff --git a/packages/vue/src/useColorMode/util.d.ts b/packages/vue/src/useColorMode/util.d.ts
new file mode 100644
index 0000000..814bd7c
--- /dev/null
+++ b/packages/vue/src/useColorMode/util.d.ts
@@ -0,0 +1 @@
+export declare function getSystemTheme();
diff --git a/packages/vue/src/useColorMode/util.ios.ts b/packages/vue/src/useColorMode/util.ios.ts
new file mode 100644
index 0000000..0811ecf
--- /dev/null
+++ b/packages/vue/src/useColorMode/util.ios.ts
@@ -0,0 +1,3 @@
+export function getSystemTheme() {
+ return UITraitCollection.currentTraitCollection.userInterfaceStyle === UIUserInterfaceStyle.Light ? 'light' : 'dark';
+}
diff --git a/packages/nativescript-vueuse/src/useColorPalette/index.md b/packages/vue/src/useColorPalette/index.md
similarity index 76%
rename from packages/nativescript-vueuse/src/useColorPalette/index.md
rename to packages/vue/src/useColorPalette/index.md
index 87074ec..364f976 100644
--- a/packages/nativescript-vueuse/src/useColorPalette/index.md
+++ b/packages/vue/src/useColorPalette/index.md
@@ -1,11 +1,13 @@
+
# useColorPalette
-Reactive color palette (dark / light / customs) for reactive styles.
-
+Reactive color palette (dark / light / customs) for reactive styles.
::: info
-In order for useColorPalette to react to theme changes you need the application themes to be controlled by [`useColorMode`](/core/useColorMode/)
+In order for useColorPalette to react to theme changes you need the application themes to be controlled by [`useColorMode`](/src/useColorMode/)
:::
## Usage
@@ -18,7 +20,7 @@ If in your application you will only have light mode and dark mode you will need
// app.ts / main.ts
import { createApp } from 'nativescript-vue';
-import { useColorMode, useColorPalette } from "@vallemar/nativescript-vueuse";
+import { useColorMode, useColorPalette } from "@nativescript-use/vue";
/* Init Palette */
useColorPalette({
@@ -30,17 +32,16 @@ useColorPalette({
createApp(Home).start();
```
-
### Advanced initialize
-This function depends on [`useColorMode`](/core/useColorMode/). If you want other themes than the default themes on the native side (light/dark) you must also initialize [`useColorMode`](/core/useColorMode/) so that the themes match useColorPalette.
+This function depends on [`useColorMode`](/src/useColorMode/). If you want other themes than the default themes on the native side (light/dark) you must also initialize [`useColorMode`](/src/useColorMode/) so that the themes match useColorPalette.
```js
// app.ts / main.ts
import { createApp } from 'nativescript-vue';
-import { useColorMode, useColorPalette } from "@vallemar/nativescript-vueuse";
+import { useColorMode, useColorPalette } from "@nativescript-use/vue";
/* Init Color mode and Palette */
useColorMode({
@@ -60,12 +61,12 @@ createApp(Home).start();
```
### Use in your application
-This is a simple example, keep in mind that when you change the theme through [`useColorMode`](/core/useColorMode/) the reactive palette will change automatically applying the colors of the new palette.
+This is a simple example, keep in mind that when you change the theme through [`useColorMode`](/src/useColorMode/) the reactive palette will change automatically applying the colors of the new palette.
```vue
+
+# useContentElementSize
+
+Reactive content size of a NativeScript view.
+
+This function returns the sum of size measurements of the children of the element passed as target.
+
+## Usage
+
+```vue
+
+
+
+
+
+
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { Ref, Readonly } from "nativescript-vue"
+import { ViewRef } from "@nativescript-use/vue";
+import { CoreTypes, View } from "@nativescript/core";
+
+export declare type ContentSizeDIP = {
+ width: CoreTypes.dip;
+ fullWidth: CoreTypes.dip;
+ height: CoreTypes.dip;
+ fullHeight: CoreTypes.dip;
+ marginTop: CoreTypes.dip;
+ marginBottom: CoreTypes.dip;
+ marginLeft: CoreTypes.dip;
+ marginRight: CoreTypes.dip;
+};
+/**
+ * Reactive content size of a NativeScript element.
+ *
+ * @param target
+ * @param options
+ */
+export declare function useContentElementSize(target: View | ViewRef, options?: {
+ onChange?: (size: ContentSizeDIP) => void;
+ initialSize?: ContentSizeDIP;
+}): {
+ width: Readonly[>;
+ fullWidth: Readonly][>;
+ height: Readonly][>;
+ fullHeight: Readonly][>;
+ marginTop: Readonly][>;
+ marginBottom: Readonly][>;
+ marginLeft: Readonly][>;
+ marginRight: Readonly][>;
+};
+
+
+```
diff --git a/packages/vue/src/useContentElementSize/index.ts b/packages/vue/src/useContentElementSize/index.ts
new file mode 100644
index 0000000..bd60af3
--- /dev/null
+++ b/packages/vue/src/useContentElementSize/index.ts
@@ -0,0 +1,126 @@
+import { ref, onMounted, readonly } from 'nativescript-vue';
+import { unrefView } from '../unrefView';
+import { ViewRef } from '../types';
+import { CoreTypes, View } from '@nativescript/core';
+import { toDeviceIndependent } from '../utils';
+
+export type ContentSizeDIP = {
+ width: CoreTypes.dip;
+ fullWidth: CoreTypes.dip;
+ height: CoreTypes.dip;
+ fullHeight: CoreTypes.dip;
+ marginTop: CoreTypes.dip;
+ marginBottom: CoreTypes.dip;
+ marginLeft: CoreTypes.dip;
+ marginRight: CoreTypes.dip;
+};
+
+/**
+ * Reactive content size of a NativeScript view.
+ *
+ * @param target
+ * @param options
+ */
+export function useContentElementSize(
+ target: View | ViewRef,
+ options?: {
+ onChange?: (size: ContentSizeDIP) => void;
+ initialSize?: ContentSizeDIP;
+ }
+) {
+ const {
+ initialSize = {
+ width: 0,
+ height: 0,
+ fullWidth: 0,
+ fullHeight: 0,
+ marginTop: 0,
+ marginBottom: 0,
+ marginLeft: 0,
+ marginRight: 0,
+ },
+ } = options ?? {};
+
+ const width = ref](initialSize.width);
+ const fullWidth = ref(initialSize.width);
+ const height = ref(initialSize.height);
+ const fullHeight = ref(initialSize.height);
+ const marginTop = ref(initialSize.marginTop);
+ const marginBottom = ref(initialSize.marginBottom);
+ const marginLeft = ref(initialSize.marginLeft);
+ const marginRight = ref(initialSize.marginRight);
+
+ function layoutChanged() {
+ const parent = unrefView(target);
+ if (parent) {
+ let computeWidth: CoreTypes.dip = 0;
+ let computeHeight: CoreTypes.dip = 0;
+ let computeMarginTop: CoreTypes.dip = 0;
+ let computeMarginBottom: CoreTypes.dip = 0;
+ let computeMarginLeft: CoreTypes.dip = 0;
+ let computeMarginRight: CoreTypes.dip = 0;
+
+ parent.eachChildView((child: View) => {
+ computeWidth += child.getActualSize().width;
+ computeHeight += child.getActualSize().height;
+ computeMarginTop += toDeviceIndependent(child.marginTop);
+ computeMarginBottom += toDeviceIndependent(child.marginBottom);
+ computeMarginLeft += toDeviceIndependent(child.marginLeft);
+ computeMarginRight += toDeviceIndependent(child.marginRight);
+ return true;
+ });
+ width.value = computeWidth;
+ height.value = computeHeight;
+ marginTop.value = computeMarginTop;
+ marginBottom.value = computeMarginBottom;
+ marginLeft.value = computeMarginLeft;
+ marginRight.value = computeMarginRight;
+ const computeFullWidth = (fullWidth.value = computeWidth + computeMarginLeft + computeMarginRight);
+ const computeFullHeight = (fullHeight.value = computeHeight + computeMarginTop + computeMarginBottom);
+ if (options?.onChange) {
+ options.onChange({
+ width: computeWidth,
+ fullWidth: computeFullWidth,
+ height: computeHeight,
+ fullHeight: computeFullHeight,
+ marginTop: computeMarginTop,
+ marginBottom: computeMarginBottom,
+ marginLeft: computeMarginLeft,
+ marginRight: computeMarginRight,
+ } as ContentSizeDIP);
+ }
+ }
+ }
+
+ onMounted(() => {
+ const view = unrefView(target);
+ if (view) {
+ view.on('layoutChanged', layoutChanged);
+ view.eachChildView((child: View) => {
+ child.on('layoutChanged', layoutChanged);
+ return true;
+ });
+
+ view.on('unloaded', () => {
+ view.off('layoutChanged', layoutChanged);
+ });
+ view.eachChildView((child: View) => {
+ child.on('unloaded', () => {
+ child.off('layoutChanged', layoutChanged);
+ });
+ return true;
+ });
+ }
+ });
+
+ return {
+ width: readonly(width),
+ fullWidth: readonly(fullWidth),
+ height: readonly(height),
+ fullHeight: readonly(fullHeight),
+ marginTop: readonly(marginTop),
+ marginBottom: readonly(marginBottom),
+ marginLeft: readonly(marginLeft),
+ marginRight: readonly(marginRight),
+ };
+}
diff --git a/packages/vue/src/useDark/index.md b/packages/vue/src/useDark/index.md
new file mode 100644
index 0000000..3dcf003
--- /dev/null
+++ b/packages/vue/src/useDark/index.md
@@ -0,0 +1,62 @@
+
+
+# useDark
+
+Reactive dark mode with auto data persistence.
+
+## Usage
+```js
+import { useDark } from "@nativescript-use/vue";
+
+const isDark = useDark();
+
+function toggleTheme(){
+ isDark.value = !isDark.value;
+}
+```
+
+::: warning
+#### Switch to device theme
+
+`useDark` is a switch between the light/dark theme of your application. If you want to activate the device theme you must use [`useColorMode`](/src/useColorMode/).
+
+```ts
+const { schema } = useColorMode();
+schema.value = "auto";
+```
+:::
+
+## CSS integration
+To control the styles in your CSS you just have to add the theme class with the prefix `ns-`.
+
+```css
+.ns-light Label{
+ color: gray;
+}
+
+.ns-dark Label{
+ color: white;
+}
+```
+
+## Integrate with TailWind CSS
+
+Integrate TaildWind CSS with the official [NativeScript plugin](https://github.com/NativeScript/tailwind) and apply styles depending on the theme. It works out of the box and no integration needs to be done
+
+```html
+
+```
+
+## Source
+
+
+## Type declaration
+
+```ts
+import { WritableComputedRef } from "nativescript-vue";
+
+export declare function useDark(): WritableComputedRef;
+
+```
\ No newline at end of file
diff --git a/packages/vue/src/useDark/index.ts b/packages/vue/src/useDark/index.ts
new file mode 100644
index 0000000..0b4bded
--- /dev/null
+++ b/packages/vue/src/useDark/index.ts
@@ -0,0 +1,17 @@
+import { computed } from 'nativescript-vue';
+import { useColorMode } from '../useColorMode';
+
+export function useDark() {
+ const { theme, schema } = useColorMode();
+
+ const isDark = computed({
+ get() {
+ return theme.value === 'dark';
+ },
+ set(v) {
+ const modeVal = v ? 'dark' : 'light';
+ schema.value = modeVal;
+ },
+ });
+ return isDark;
+}
diff --git a/packages/nativescript-vueuse/src/useElementSize/index.md b/packages/vue/src/useElementSize/index.md
similarity index 64%
rename from packages/nativescript-vueuse/src/useElementSize/index.md
rename to packages/vue/src/useElementSize/index.md
index d118f47..d33ac61 100644
--- a/packages/nativescript-vueuse/src/useElementSize/index.md
+++ b/packages/vue/src/useElementSize/index.md
@@ -1,6 +1,6 @@
----
-category: Elements
----
+
# useElementSize
@@ -9,27 +9,29 @@ Reactive size of a NativeScript View.
## Usage
```vue
-
-
-
-
-
-
+
+
+
+
+
+
```
-
+
+## Source
+
## Type declaration
```ts
import { Ref } from "nativescript-vue"
-import { ViewRef } from "@vallemar/nativescript-vueuse";
-import { CoreTypes } from "@nativescript/core/core-types";
+import { ViewRef } from "@nativescript-use/vue";
+import { CoreTypes, View } from "@nativescript/core";
export type SizeDIP = {
width: CoreTypes.dip;
@@ -41,7 +43,7 @@ export type SizeDIP = {
* @param target
* @param options
*/
-export declare function useElementSize(target: ViewRef, options?: {
+export declare function useElementSize(target: View | ViewRef, options?: {
onChange?: (size: SizeDIP) => void;
initialSize?: SizeDIP;
}): {
diff --git a/packages/vue/src/useElementSize/index.ts b/packages/vue/src/useElementSize/index.ts
new file mode 100644
index 0000000..58e7305
--- /dev/null
+++ b/packages/vue/src/useElementSize/index.ts
@@ -0,0 +1,47 @@
+import { ref, onMounted } from 'nativescript-vue';
+import { unrefView } from '../unrefView';
+import { ViewRef } from '../types';
+import { CoreTypes, View } from '@nativescript/core';
+
+export type SizeDIP = {
+ width: CoreTypes.dip;
+ height: CoreTypes.dip;
+};
+/**
+ * Reactive size of a NativeScript element.
+ *
+ * @param target
+ * @param options
+ */
+export function useElementSize(target: View | ViewRef, options?: { onChange?: (size: SizeDIP) => void; initialSize?: SizeDIP }) {
+ const { initialSize = { width: 0, height: 0 } } = options ?? {};
+
+ const width = ref(initialSize.width);
+ const height = ref(initialSize.height);
+
+ function layoutChanged() {
+ const size = unrefView(target)?.getActualSize() as SizeDIP;
+ if (size) {
+ width.value = size.width;
+ height.value = size.height;
+ if (options?.onChange) {
+ options.onChange(size);
+ }
+ }
+ }
+
+ onMounted(() => {
+ const view = unrefView(target);
+ if (view) {
+ view.on('layoutChanged', layoutChanged);
+ view.on('unloaded', () => {
+ view.off('layoutChanged', layoutChanged);
+ });
+ }
+ });
+
+ return {
+ width,
+ height,
+ };
+}
diff --git a/packages/nativescript-vueuse/src/useEventListener/index.md b/packages/vue/src/useEventListener/index.md
similarity index 76%
rename from packages/nativescript-vueuse/src/useEventListener/index.md
rename to packages/vue/src/useEventListener/index.md
index 0f01841..891b921 100644
--- a/packages/nativescript-vueuse/src/useEventListener/index.md
+++ b/packages/vue/src/useEventListener/index.md
@@ -1,3 +1,6 @@
+
# useEventListener
@@ -6,14 +9,9 @@ Use EventListener with ease. Register using view.on on mounted, and view.off aut
## Usage
```vue
-
-
-
-
-
+
+
+
+
+
```
-
+
+## Source
+
## Type declaration
```ts
-import { ViewRef } from "@vallemar/nativescript-vueuse";
-import { EventData, GestureEventData, ShownModallyData, View } from "@nativescript/core";
+import { ViewRef } from "@nativescript-use/vue";
+import { EventData, GestureEventData, ShownModallyData, View, CreateViewEventData } from "@nativescript/core";
type ViewEventData = Omit & {
object: T;
@@ -48,6 +53,9 @@ type ViewGestureEventData = Omit & {
type ViewShownModallyData = Omit & {
object: T;
};
+type CreatingViewEventData = Omit & {
+ object: Placeholder;
+};
interface Event {
/* Lifecycle */
loaded?: (eventData: ViewEventData) => void;
@@ -65,11 +73,15 @@ interface Event {
/* Modals */
showingModally?: (eventData: ViewShownModallyData) => void;
shownModally?: (eventData: ViewShownModallyData) => void;
- /* Accessibility */
+/* Accessibility */
accessibilityBlur?: (eventData: ViewEventData) => void;
accessibilityFocus?: (eventData: ViewEventData) => void;
accessibilityFocusChanged?: (eventData: ViewEventData) => void;
accessibilityPerformEscape?: (eventData: ViewEventData) => void;
+ /* Layouts */
+ scroll?: (eventData: ViewScrollEventData) => void;
+ /* Components */
+ creatingView?: (eventData: CreatingViewEventData) => void;
}
/**
* Register using view.on on mounted, and view.off automatically on unmounted.
@@ -78,7 +90,7 @@ interface Event {
* @param target
* @param events
*/
-export declare function useEventListener(target: ViewRef, events: Event): {
+export declare function useEventListener(target: T | ViewRef, events: Event): {
cleanup: () => void;
};
diff --git a/packages/vue/src/useEventListener/index.ts b/packages/vue/src/useEventListener/index.ts
new file mode 100644
index 0000000..bb3a6b3
--- /dev/null
+++ b/packages/vue/src/useEventListener/index.ts
@@ -0,0 +1,71 @@
+import { CreateViewEventData, EventData, GestureEventData, Placeholder, ScrollEventData, ScrollView, ShownModallyData, View } from '@nativescript/core';
+import { onMounted, onUnmounted } from 'nativescript-vue';
+import { ViewRef } from '../types';
+import { unrefView } from '../unrefView';
+
+type ViewEventData = Omit & { object: T };
+type ViewGestureEventData = Omit & { object: T };
+type ViewShownModallyData = Omit & { object: T };
+type ViewScrollEventData = Omit & { object: T };
+type CreatingViewEventData = Omit & {
+ object: Placeholder;
+};
+interface Event {
+ /* Lifecycle */
+ loaded?: (eventData: ViewEventData) => void;
+ unloaded?: (eventData: ViewEventData) => void;
+ layoutChanged?: (eventData: ViewEventData) => void;
+ /* Gesture */
+ tap?: (eventData: ViewGestureEventData) => void;
+ doubleTap?: (eventData: ViewGestureEventData) => void;
+ pinch?: (eventData: ViewGestureEventData) => void;
+ pan?: (eventData: ViewGestureEventData) => void;
+ swipe?: (eventData: ViewGestureEventData) => void;
+ rotation?: (eventData: ViewGestureEventData) => void;
+ longPress?: (eventData: ViewGestureEventData) => void;
+ touch?: (eventData: ViewGestureEventData) => void;
+ /* Modals */
+ showingModally?: (eventData: ViewShownModallyData) => void;
+ shownModally?: (eventData: ViewShownModallyData) => void;
+ /* Accessibility */
+ accessibilityBlur?: (eventData: ViewEventData) => void;
+ accessibilityFocus?: (eventData: ViewEventData) => void;
+ accessibilityFocusChanged?: (eventData: ViewEventData) => void;
+ accessibilityPerformEscape?: (eventData: ViewEventData) => void;
+ /* Layouts */
+ scroll?: (eventData: ViewScrollEventData) => void;
+ /* Components */
+ creatingView?: (eventData: CreatingViewEventData) => void;
+}
+
+/**
+ * Register using view.on on mounted, and view.off automatically on unmounted.
+ *
+ *
+ * @param target
+ * @param events
+ */
+export function useEventListener(target: T | ViewRef, events: Event) {
+ const el = target;
+
+ const fireEvent = (onEvent: any) => (args: any) => onEvent(args);
+
+ onMounted(() => {
+ Object.keys(events).forEach((event) => {
+ unrefView(el)?.on(event, fireEvent((events as any)[event]));
+ });
+ });
+
+ onUnmounted(() => {
+ cleanup();
+ });
+
+ function cleanup() {
+ Object.keys(events).forEach((event) => {
+ unrefView(el)?.off(event, fireEvent((events as any)[event]));
+ });
+ }
+ return {
+ cleanup,
+ };
+}
diff --git a/packages/vue/src/useFadeElement/index.md b/packages/vue/src/useFadeElement/index.md
new file mode 100644
index 0000000..cf49bf3
--- /dev/null
+++ b/packages/vue/src/useFadeElement/index.md
@@ -0,0 +1,64 @@
+
+
+# useFadeElement
+
+Change opacity and visibility with animation of a NativeScript element.
+
+## Usage
+
+```vue
+
+
+
+
+
+
+
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { CoreTypes } from '@nativescript/core';
+import { Ref } from "nativescript-vue"
+import { ViewRef } from "@nativescript-use/vue";
+/**
+ * Change opacity and visibility with animation of a NativeScript element.
+ *
+ * @param target
+ * @param options
+ */
+export declare function useFadeElement(target: ViewRef, options?: {
+ initial?: {
+ opacity: number;
+ visibility: CoreTypes.VisibilityType;
+ };
+ animationDuration?: number;
+}): {
+ isVisible: Ref;
+ show: () => Promise;
+ hide: () => Promise;
+ toggle: () => Promise;
+};
+
+```
\ No newline at end of file
diff --git a/packages/vue/src/useFadeElement/index.ts b/packages/vue/src/useFadeElement/index.ts
new file mode 100644
index 0000000..c530ed9
--- /dev/null
+++ b/packages/vue/src/useFadeElement/index.ts
@@ -0,0 +1,64 @@
+import { watch, ref } from 'nativescript-vue';
+import { ViewRef } from '../types';
+import { unrefView } from '../unrefView';
+import { View, CoreTypes } from '@nativescript/core';
+import { useEventListener } from '../useEventListener';
+
+/**
+ * Change opacity and visibility with animation of a NativeScript element.
+ *
+ * @param target
+ * @param options
+ */
+export function useFadeElement(
+ target: ViewRef,
+ options?: {
+ initial?: { opacity: number; visibility: CoreTypes.VisibilityType };
+ animationDuration?: number;
+ }
+) {
+ const { animationDuration = 250 } = options ?? {};
+ const { opacity = 0, visibility = CoreTypes.Visibility.collapsed } = options?.initial ?? {};
+
+ const isVisible = ref(opacity !== 0);
+
+ useEventListener(target, {
+ loaded(args) {
+ args.object.opacity = opacity;
+ args.object.visibility = visibility;
+ },
+ });
+ watch(isVisible, () => {
+ apply(isVisible.value);
+ });
+
+ function apply(show: boolean) {
+ return new Promise((resolve) => {
+ const view = unrefView(target);
+ if (view) {
+ isVisible.value = show;
+ if (show) {
+ view.visibility = CoreTypes.Visibility.visible;
+ }
+ view
+ ?.animate({
+ opacity: show ? 1 : 0,
+ duration: animationDuration,
+ })
+ .then(() => {
+ if (!show) {
+ view.visibility = CoreTypes.Visibility.collapsed;
+ }
+ resolve();
+ });
+ }
+ });
+ }
+
+ return {
+ isVisible,
+ show: () => apply(true),
+ hide: () => apply(false),
+ toggle: () => apply(!isVisible.value),
+ };
+}
diff --git a/packages/vue/src/useIntersectionObserver/index.md b/packages/vue/src/useIntersectionObserver/index.md
new file mode 100644
index 0000000..94bb83f
--- /dev/null
+++ b/packages/vue/src/useIntersectionObserver/index.md
@@ -0,0 +1,77 @@
+
+
+# useIntersectionObserver
+
+Reactive detects that a target element visibility.
+
+Tracks a view inside a `ScrollView` and notifies when the view is visible on the screen.
+
+## Usage
+
+```vue
+
+
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+ ...
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { Ref, Readonly } from "nativescript-vue"
+import { ViewRef } from "@nativescript-use/vue";
+import { ScrollView, View } from "@nativescript/core";
+
+/**
+ * Reactive detects that a target element visibility.
+ *
+ * @param target
+ * @param parentView
+ * @param options
+ */
+export declare function useIntersectionObserver(target: View | ViewRef, parentView: ViewRef, options?: {
+ onChange?: (isVisible: boolean) => void;
+}): {
+ isVisible: Readonly[>;
+ stopTrack: () => void;
+};
+
+```
+
+## Core dependency
+[@nativescript-use/nativescript-intersection-observer](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-intersection-observer)
diff --git a/packages/vue/src/useIntersectionObserver/index.ts b/packages/vue/src/useIntersectionObserver/index.ts
new file mode 100644
index 0000000..5965d85
--- /dev/null
+++ b/packages/vue/src/useIntersectionObserver/index.ts
@@ -0,0 +1,49 @@
+import { IntersectionObserver } from '@nativescript-use/nativescript-intersection-observer';
+import { ScrollView, View } from '@nativescript/core';
+import { readonly, ref } from 'nativescript-vue';
+import { ViewRef } from '../types';
+import { unrefView } from '../unrefView';
+import { useEventListener } from '../useEventListener';
+
+/**
+ * Reactive detects that a target element visibility.
+ *
+ * @param target
+ * @param options
+ */
+export function useIntersectionObserver(target: View | ViewRef, parentView: ViewRef], options?: { onChange?: (isVisible: boolean) => void }) {
+ let isVisibleInternal = false;
+ let isVisible = ref(isVisibleInternal);
+ let intersectionObserver: IntersectionObserver;
+
+ useEventListener(parentView, {
+ loaded: () => {
+ setTimeout(() => {
+ const view = unrefView(target);
+ if (view) {
+ const parent = unrefView(parentView);
+ intersectionObserver = new IntersectionObserver();
+ isVisibleInternal = intersectionObserver.isVisible(view, parent);
+ isVisible.value = isVisibleInternal;
+
+ intersectionObserver.track(view, parent, (visible) => {
+ if (isVisibleInternal != visible) {
+ isVisibleInternal = visible;
+ isVisible.value = visible;
+ if (options?.onChange) options.onChange(visible);
+ }
+ });
+ }
+ }, 10);
+ },
+ });
+
+ function stopTrack() {
+ intersectionObserver.stopTrack();
+ }
+
+ return {
+ isVisible: readonly(isVisible),
+ stopTrack,
+ };
+}
diff --git a/packages/nativescript-vueuse/src/useKeyboard/index.md b/packages/vue/src/useKeyboard/index.md
similarity index 75%
rename from packages/nativescript-vueuse/src/useKeyboard/index.md
rename to packages/vue/src/useKeyboard/index.md
index 12cb2e8..85f94bd 100644
--- a/packages/nativescript-vueuse/src/useKeyboard/index.md
+++ b/packages/vue/src/useKeyboard/index.md
@@ -1,6 +1,6 @@
----
-category: Elements
----
+
# useKeyboard
@@ -11,7 +11,7 @@ Reactive keyboard state. It also provides methods to open or close the keyboard.
```vue
```
-
+
+## Source
+
## Type declaration
```ts
import { Ref } from "nativescript-vue"
-import { ViewRef } from "@vallemar/nativescript-vueuse";
+import { ViewRef } from "@nativescript-use/vue";
+import { View } from "@nativescript/core";
/**
* Reactive keyboard state. It also provides methods to open or close the keyboard.
@@ -80,11 +82,14 @@ import { ViewRef } from "@vallemar/nativescript-vueuse";
*/
export declare function useKeyboard(options?: {
onChange?: (isOpen: boolean) => void;
- defaultTarget?: ViewRef;
+ defaultTarget?: View | ViewRef;
}): {
isOpen: Readonly[>;
- open: (target?: ViewRef) => void;
+ open: (target?: View | ViewRef) => void;
close: () => void;
};
```
+
+## Core dependency
+[@nativescript-use/nativescript-keyboard](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-keyboard)
\ No newline at end of file
diff --git a/packages/vue/src/useKeyboard/index.ts b/packages/vue/src/useKeyboard/index.ts
new file mode 100644
index 0000000..6692af1
--- /dev/null
+++ b/packages/vue/src/useKeyboard/index.ts
@@ -0,0 +1,52 @@
+import { onMounted, onUnmounted, readonly, ref } from 'nativescript-vue';
+import { ViewRef } from '../types';
+import { unrefView } from '../unrefView';
+import { Keyboard } from '@nativescript-use/nativescript-keyboard';
+import { onApplicationMounted } from '../onApplicationMounted';
+import { warn } from '../utils';
+import { View } from '@nativescript/core';
+
+/**
+ * Reactive size of a NativeScript element.
+ *
+ * @param target
+ * @param options
+ */
+export function useKeyboard(options?: { onChange?: (isOpen: boolean) => void; defaultTarget?: View | ViewRef }) {
+ const isOpen = ref(false);
+ const keyboardCore = new Keyboard();
+
+ //TODO: fix this
+ onMounted(() => {
+ onApplicationMounted(() => {
+ keyboardCore.onChangeVisibility((status: boolean) => {
+ if (isOpen.value !== status) {
+ isOpen.value = status;
+ if (options?.onChange) options.onChange(status);
+ }
+ });
+ });
+ });
+
+ onUnmounted(() => {
+ keyboardCore.offChangeVisibility();
+ });
+
+ const open = (target?: View | ViewRef) => {
+ const viewTarget = unrefView(target!);
+ const viewDefaultTarget = options?.defaultTarget ? unrefView(options?.defaultTarget!) : null;
+
+ if (viewTarget) {
+ keyboardCore.open(viewTarget);
+ } else if (viewDefaultTarget) {
+ keyboardCore.open(viewDefaultTarget);
+ } else {
+ warn('Error. Need to define a view to apply focus.');
+ }
+ };
+ return {
+ isOpen: readonly(isOpen),
+ open,
+ close: keyboardCore.close,
+ };
+}
diff --git a/packages/vue/src/useMediaQuery/index.md b/packages/vue/src/useMediaQuery/index.md
new file mode 100644
index 0000000..8e04bae
--- /dev/null
+++ b/packages/vue/src/useMediaQuery/index.md
@@ -0,0 +1,44 @@
+
+
+# useMediaQuery
+
+Reactive Media Query. Returns a reactive variable that reacts to orientation changes.
+
+## Usage
+
+```vue
+
+
+```
+
+## Source
+]
+
+## Type declaration
+```ts
+import { Ref } from "nativescript-vue"
+
+/**
+ * Reactive Media Query.
+ *
+ * @param mediaQueryString
+ */
+export declare function useMediaQuery(mediaQueryString: string): Ref;
+
+```
+
+## Core dependency
+[@nativescript-use/nativescript-media-query](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-media-query)
\ No newline at end of file
diff --git a/packages/vue/src/useMediaQuery/index.ts b/packages/vue/src/useMediaQuery/index.ts
new file mode 100644
index 0000000..44b544c
--- /dev/null
+++ b/packages/vue/src/useMediaQuery/index.ts
@@ -0,0 +1,25 @@
+import { onMounted, onUnmounted, ref } from 'nativescript-vue';
+import { matchMedia, MediaQueryList, MediaQueryListListener } from '@nativescript-use/nativescript-media-query';
+
+/**
+ * Reactive Media Query.
+ *
+ * @param mediaQueryString
+ */
+export function useMediaQuery(mediaQueryString: string) {
+ const mql = matchMedia(mediaQueryString);
+ const matches = ref(mql.matches);
+
+ const onChange: MediaQueryListListener = (event: MediaQueryList) => {
+ matches.value = event.matches;
+ };
+
+ onMounted(() => {
+ mql.addListener(onChange);
+ });
+ onUnmounted(() => {
+ mql.removeListener(onChange);
+ });
+
+ return matches;
+}
diff --git a/packages/nativescript-vueuse/src/useRootLayout/index.md b/packages/vue/src/useRootLayout/index.md
similarity index 74%
rename from packages/nativescript-vueuse/src/useRootLayout/index.md
rename to packages/vue/src/useRootLayout/index.md
index 2163fa7..0b29688 100644
--- a/packages/nativescript-vueuse/src/useRootLayout/index.md
+++ b/packages/vue/src/useRootLayout/index.md
@@ -1,3 +1,6 @@
+
# useRootLayout
@@ -6,23 +9,23 @@ Utility for RootLayout view. [RootLayout official documentation](https://docs.na
## Usage
```vue
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
```
-
::: tip
If you need multiple rootLayouts you can alias the methods and references returned by `useRootLayout`.
:::
```vue
-
-
-
-
+
+
+
+
```
+## Source
+
+
## Type declaration
```ts
import { RootLayoutOptions, View } from "@nativescript/core";
@@ -93,7 +105,9 @@ import { RootLayoutOptions, View } from "@nativescript/core";
*/
export declare function useRootLayout(component: any, options?: {
props?: any;
+ on?: Record any>;
rootLayoutOption?: RootLayoutOptions;
+ closeTimerMillis?: number;
onClose?: () => void;
}): {
show: () => Promise;
@@ -101,4 +115,5 @@ export declare function useRootLayout(component: any, options?: {
isShow: Ref;
view: View;
};
+
```
diff --git a/packages/vue/src/useRootLayout/index.ts b/packages/vue/src/useRootLayout/index.ts
new file mode 100644
index 0000000..6ea189f
--- /dev/null
+++ b/packages/vue/src/useRootLayout/index.ts
@@ -0,0 +1,92 @@
+import { createNativeView, ref } from 'nativescript-vue';
+import { Frame, RootLayoutOptions, View, ViewBase, getRootLayout } from '@nativescript/core';
+import { onApplicationMounted } from '../onApplicationMounted';
+import { warn } from '../utils';
+
+/**
+ * Utility for the RootLayout view.
+ *
+ * @param component
+ * @param options
+ */
+export function useRootLayout(
+ component: any,
+ options?: {
+ props?: any;
+ on?: Record any>;
+ rootLayoutOption?: RootLayoutOptions;
+ onClose?: () => void;
+ closeTimerMillis?: number;
+ }
+) {
+ const isShow = ref(false);
+
+ const listeners = Object.entries(options?.on ?? {}).reduce((listeners, [key, value]) => {
+ listeners['on' + key.charAt(0).toUpperCase() + key.slice(1)] = value;
+ return listeners;
+ }, {} as { [key: string]: (...args: any[]) => any });
+
+ const propsAndListeners = Object.assign(options?.props ?? {}, listeners);
+
+ let view: View | null = null;
+
+ function buildView() {
+ const node = createNativeView(component, propsAndListeners);
+ node.mount();
+ view = node.nativeView;
+
+ view.on(ViewBase.unloadedEvent, () => {
+ isShow.value = false;
+ if (options?.onClose) options.onClose();
+ });
+ }
+
+ onApplicationMounted(() => {
+ if (!view) buildView();
+ });
+
+ function _show(resolve, reject) {
+ isShow.value = true;
+ if (options?.closeTimerMillis) {
+ setTimeout(() => {
+ getRootLayout().close(view, options?.rootLayoutOption?.animation?.exitTo);
+ }, options.closeTimerMillis);
+ }
+ getRootLayout()
+ .open(view, options?.rootLayoutOption)
+ .then((params) => {
+ resolve(params);
+ })
+ .catch((error) => {
+ reject(error);
+ });
+ }
+
+ function show() {
+ const promise = new Promise((resolve, reject) => {
+ setTimeout(() => {
+ if (!view && Frame.topmost()) {
+ buildView();
+ _show(resolve, reject);
+ } else if (view) {
+ _show(resolve, reject);
+ } else {
+ reject();
+ warn('[useRootLayout] If you are using show() in your main view call show() inside the onApplicationMounted hook or onMounted');
+ }
+ }, 0);
+ });
+ return promise;
+ }
+
+ function close() {
+ getRootLayout().close(view);
+ }
+
+ return {
+ show,
+ close,
+ isShow,
+ view,
+ };
+}
diff --git a/packages/nativescript-vueuse/src/useScreenOrientation/index.md b/packages/vue/src/useScreenOrientation/index.md
similarity index 67%
rename from packages/nativescript-vueuse/src/useScreenOrientation/index.md
rename to packages/vue/src/useScreenOrientation/index.md
index 8d9a6de..f845476 100644
--- a/packages/nativescript-vueuse/src/useScreenOrientation/index.md
+++ b/packages/vue/src/useScreenOrientation/index.md
@@ -1,3 +1,7 @@
+
+
# useScreenOrientation
Reactive screen orientation and utilities to manage the orientation.
@@ -6,7 +10,7 @@ Reactive screen orientation and utilities to manage the orientation.
```vue
+
+# useStorage
+
+Create a reactive ref that can be used to access & modify [ApplicationSettings](https://docs.nativescript.org/core/application-settings) and using [useStorage of VueUse](https://vueuse.org/core/useStorage/#usestorage).
+
+Uses [localStorage plugin](https://github.com/NativeScript-Use/NativeScript-Use/blob/main/packages/nativescript-localstorage/README.md) by default, other storage sources be specified via third argument.
+
+::: warning
+#### Breaking changes 0.0.43
+
+Breaking changes since version 0.0.43. It is now not used as a utility to access ApplicationSettings values.
+
+**Now returns a reactive object that is binded with ApplicationSettings.**
+:::
+
+## Usage
+
+```ts
+import { useStorage } from '@nativescript-use/vue'
+
+// bind object
+const state = useStorage('my-store', { hello: 'hi', greeting: 'Hello' }) // returns Ref<{ hello: string, greeting: string }>
+
+state.value.hello = 'Updated Hi!'; // 🔄 Automatically synchronize with ApplicationSettings (localStorage)
+
+// bind boolean
+const flag = useStorage('my-flag', true) // returns Ref
+
+flag.value = false; // 🔄 Automatically synchronize with ApplicationSettings (localStorage)
+
+// bind number
+const count = useStorage('my-count', 0) // returns Ref
+
+count.value = 15; // 🔄 Automatically synchronize with ApplicationSettings (localStorage)
+
+
+// delete data from storage
+state.value = null
+```
+
+You can find all the documentation at [useStorage of Vue Use](https://vueuse.org/core/useStorage/#usestorage).
+
+## Source
+
+
+## Type declaration
+
+```ts
+import { LocalStorage } from '@nativescript-use/nativescript-localstorage';
+import { RemovableRef, UseStorageOptions } from '@vueuse/core';
+
+export declare function useStorage(
+ key: K,
+ initialValue: T,
+ storage?: LocalStorage,
+ options?: UseStorageOptions
+): RemovableRef;
+```
\ No newline at end of file
diff --git a/packages/vue/src/useStorage/index.ts b/packages/vue/src/useStorage/index.ts
new file mode 100644
index 0000000..e72e580
--- /dev/null
+++ b/packages/vue/src/useStorage/index.ts
@@ -0,0 +1,18 @@
+import localStorage, { LocalStorage } from '@nativescript-use/nativescript-localstorage';
+import { useStorage as useStorageCore, UseStorageOptions } from '@vueuse/core';
+
+function createStorage(key: string, initialValue: T, storage: LocalStorage, options?: UseStorageOptions) {
+ return useStorageCore(
+ key,
+ initialValue,
+ storage,
+ Object.assign(options ?? {}, {
+ listenToStorageChanges: false,
+ window: null,
+ })
+ );
+}
+
+export function useStorage(key: K, initialValue: T, storage?: LocalStorage, options?: UseStorageOptions) {
+ return createStorage(key, initialValue, storage ?? localStorage, options);
+}
diff --git a/packages/vue/src/useSyncObservableArray/index.md b/packages/vue/src/useSyncObservableArray/index.md
new file mode 100644
index 0000000..f101682
--- /dev/null
+++ b/packages/vue/src/useSyncObservableArray/index.md
@@ -0,0 +1,164 @@
+
+
+# useSyncObservableArray
+
+Reactive synchronization between a reactive array with [ObservableArray](https://docs.nativescript.org/ui-and-styling.html#rootlayout).
+
+Generate an ObservableArray that will listen for changes in a reactive Vue array and apply them to the ObservableArray. Useful to use together with [ListView](https://docs.nativescript.org/ui/list-view) and [UI-CollectionView](https://github.com/nativescript-community/ui-collectionview)
+
+## Usage
+### With reactivity
+```vue
+
+```
+
+### Without reactivity (manual synchronization)
+```vue
+
+```
+
+## Performance
+Keep in mind that searching for changes in very large arrays is expensive so keep these points in mind when using useSyncObservableArray.
+- Use `addRemoveByField` to indicate a unique property of each array element, for example the `id`.
+- The process to search for changes consists of 3 phases:
+ - Search for deleted items. Option `checkRemoved`.
+ - Search for added items. Option `checkAdded`.
+ - Check for updates on items. Option `checkUpdates`.
+
+By default all 3 phases are activated. Use these parameters to indicate which operations you want to detect. An example, if you only want to track updates, use the following configuration:
+
+```vue
+
+```
+
+### `pushAllInFirstSync`
+::: warning
+#### `@Deprecated from v0.0.46`
+
+ObservableArray will sync without checking for differences if it is empty. This improves performance and this option is no longer needed.
+:::
+
+A typical case is to declare a reactive array next to `useSyncObservableArray` and then make a request to a service to bring us all the information. In this scenario, the fastest thing is to directly synchronize the ObservableArray without checking for updates. With the property `pushAllInFirstSync: true` we indicate that the data is inserted in the first synchronization
+
+## Hooks
+### `onPreUpdate`
+To have native performance in Lists/CollectionView, the recycling of items provided by Android/iOS is implemented. When we use these views from vue, the normal thing is to access calculated properties in our template, this causes a loss of performance when the calculation carried out is slow. To mitigate this we must calculate the field before adding it to the `ObservableArray`, for this we have the `onPreUpdate` hook, it allows the object to be mutated before adding it to the `ObservableArray` (this mutation will not affect its reactive object).
+
+Note that in this case the scrolling will be fast, but the initial loading of the data will be slower since it performs the calculation before inserting the elements.
+
+❌ Don't do this
+```vue
+
+
+
+
+
+
+
+
+```
+
+✅ Do this
+```vue
+
+
+
+
+
+
+
+
+
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { ObservableArray } from "@nativescript/core";
+import { Ref } from "nativescript-vue";
+/**
+ * Reactive synchronization between a reactive array with ObservableArray.
+ *
+ * @param arrayWatchTarget
+ * @param options
+ */
+
+export declare function useSyncObservableArray(arrayRef: Ref | T[], options?: {
+ addRemoveByField?: string;
+ excludeCompareFields?: string[];
+ watchUpdates?: boolean;
+ checkRemoved?: boolean;
+ checkAdded?: boolean;
+ checkUpdates?: boolean;
+ pushAllInFirstSync?: boolean;
+ initialDelay?: number;
+ onPushInitialData?: () => void;
+ onPreUpdate?: preUpdate;
+}): {
+ sync: (newArray?: Ref | T[]) => void;
+ observableArray: ObservableArray;
+};
+```
\ No newline at end of file
diff --git a/packages/vue/src/useSyncObservableArray/index.ts b/packages/vue/src/useSyncObservableArray/index.ts
new file mode 100644
index 0000000..2963525
--- /dev/null
+++ b/packages/vue/src/useSyncObservableArray/index.ts
@@ -0,0 +1,179 @@
+import { ObservableArray } from '@nativescript/core';
+import { Ref, isReactive, isRef, toRaw, watch } from 'nativescript-vue';
+
+export enum OnPreUpdateType {
+ Add,
+ Update,
+ Delete,
+}
+/* export enum OnPreSycType {
+ Initial,
+ Update
+} */
+
+type NotAnyResult = [J] extends [undefined] ? TypeToCheck : J;
+
+type preUpdate = (item: ReactiveItem, index: number, updateType: OnPreUpdateType) => OAItem;
+
+const baseExcludeCompareFields = { startingSide: null, menuOpened: null };
+
+/**
+ * Reactive synchronization between a reactive array with ObservableArray.
+ *
+ * @param arrayWatchTarge
+ * @param options
+ */
+export function useSyncObservableArray(
+ arrayRef: Ref | ReactiveItem[],
+ options: {
+ addRemoveByField?: string;
+ excludeCompareFields?: string[];
+ watchUpdates?: boolean;
+ checkRemoved?: boolean;
+ checkAdded?: boolean;
+ checkUpdates?: boolean;
+ initialDelay?: number;
+ /**
+ * @deprecated ObservableArray will sync without checking for differences if it is empty. Applied since v0.0.46
+ */
+ pushAllInFirstSync?: boolean;
+ // onPreSync?: preSync,
+ onPushInitialData?: () => void;
+ onPreUpdate?: preUpdate;
+ } = { addRemoveByField: '' }
+) {
+ const { initialDelay = 0, checkRemoved = true, pushAllInFirstSync = false, watchUpdates = false, checkAdded = true, checkUpdates = true, excludeCompareFields = undefined, addRemoveByField /* , onPreSync = undefined */, onPreUpdate = undefined, onPushInitialData = undefined } = options;
+
+ const excludeFields = {
+ ...baseExcludeCompareFields,
+ ...excludeCompareFields?.reduce((a: any, b) => {
+ a[b] = null;
+ return a;
+ }, {}),
+ };
+ let firstSync = true;
+ //TODO: runOnPreSync
+ //let clearArray = runOnPreSync(onPreSync, getClearArray(arrayRef), OnPreSycType.Initial);
+ let clearArray = getClearArray(arrayRef);
+ if (onPreUpdate) {
+ clearArray = clearArray.map((item: ReactiveItem, index: number) => {
+ return runOnPreUpdate(onPreUpdate, item, index, OnPreUpdateType.Add);
+ });
+ }
+
+ const observableArray = createAndPushInitialData(clearArray, initialDelay, onPushInitialData) as ObservableArray>;
+
+ if (watchUpdates && (isReactive(arrayRef) || isRef(arrayRef))) {
+ watch(arrayRef, () => sync(), { deep: true });
+ }
+
+ function sync(newArray?: any) {
+ const itemList = newArray ? getClearArray(newArray) : getClearArray(arrayRef);
+ //console.time("TIME_[useSyncObservableArray.sync]");
+ //TODO: runOnPreSync
+ //const clearArray = newArray ? getClearArray(newArray) : getClearArray(arrayRef);
+ //const itemList = runOnPreSync(onPreSync, clearArray, OnPreSycType.Update);
+ //console.log('Processing_[useSyncObservableArray.sync.itemList.length] ' + itemList.length);
+ if (observableArray.length === 0 || (pushAllInFirstSync && firstSync)) {
+ firstSync = false;
+ observableArray.push(...itemList);
+ return;
+ }
+
+ // If the array is empty, we will clear the observableArray
+ if (itemList.length === 0 && observableArray.length !== 0) {
+ observableArray.splice(0, observableArray.length);
+ return;
+ }
+
+ if (checkRemoved) {
+ const indexRemoved: number[] = [];
+ observableArray.forEach((itemObservable: any, index: number) => {
+ const findItem = addRemoveByField ? itemList.find((item: any) => item[addRemoveByField] === itemObservable[addRemoveByField]) : itemList.find((item: any) => isEqualObject(item, itemObservable, excludeFields));
+ if (!findItem) {
+ indexRemoved.push(index);
+ }
+ });
+
+ indexRemoved.forEach((index) => {
+ runOnPreUpdate(onPreUpdate, itemList[index], index, OnPreUpdateType.Delete);
+ observableArray.splice(index, 1);
+ });
+ }
+
+ if (checkAdded) {
+ const indexAdd: number[] = [];
+ itemList.forEach((item: any, index: number) => {
+ const findItem = addRemoveByField ? observableArray.find((itemObservable: any) => itemObservable[addRemoveByField] === item[addRemoveByField]) : observableArray.find((itemObservable: any) => isEqualObject(itemObservable, item, excludeFields));
+ if (!findItem) {
+ indexAdd.push(index);
+ }
+ });
+ indexAdd.forEach((index) => {
+ itemList[index] = runOnPreUpdate(onPreUpdate, itemList[index], index, OnPreUpdateType.Add);
+ observableArray.splice(index, 0, itemList[index]);
+ });
+ }
+
+ if (checkUpdates) {
+ itemList.forEach((item: any, index: number) => {
+ const itemObservable = observableArray.getItem(index);
+ if (!isEqualObject(itemObservable, item, excludeFields)) {
+ item = runOnPreUpdate(onPreUpdate, item, index, OnPreUpdateType.Add);
+ observableArray.setItem(index, item);
+ }
+ });
+ }
+ //console.timeEnd("TIME_[useSyncObservableArray.sync]");
+ }
+
+ return {
+ sync,
+ observableArray,
+ };
+}
+
+function createAndPushInitialData(clearArray: NotAnyResult[], initialDelay: number, onPushInitialData: () => void) {
+ let observableArray = new ObservableArray>([]);
+ if (initialDelay != 0) {
+ setTimeout(() => {
+ observableArray.push(...clearArray);
+ if (onPushInitialData) {
+ onPushInitialData();
+ }
+ }, initialDelay);
+ } else {
+ observableArray.push(...clearArray);
+ if (onPushInitialData) {
+ onPushInitialData();
+ }
+ }
+ return observableArray;
+}
+/* function runOnPreSync(onPreSync: preSync, items: T[], type: OnPreSycType): T[] | J[] {
+ if (onPreSync) return onPreSync(items, type);
+ return items;
+} */
+
+function runOnPreUpdate(onPreUpdated: preUpdate | undefined, item: ReactiveItem, index: number, type: OnPreUpdateType): ReactiveItem | OAItem {
+ if (onPreUpdated) return onPreUpdated(item, index, type);
+ return item;
+}
+
+function getClearArray(array: Ref | ReactiveItem[]) {
+ return cloneObject(extractArray(array));
+}
+
+function extractArray(array: Ref | T[]) {
+ return isRef(array) ? array.value : array;
+}
+
+function isEqualObject(a: any, b: any, excludeFields: any) {
+ const aObject = { ...a, ...excludeFields };
+ const bObject = { ...b, ...excludeFields };
+ return JSON.stringify(aObject) === JSON.stringify(bObject);
+}
+
+function cloneObject(object: any) {
+ return JSON.parse(JSON.stringify(toRaw(object)));
+}
diff --git a/packages/vue/src/useWorker/index.md b/packages/vue/src/useWorker/index.md
new file mode 100644
index 0000000..0da3844
--- /dev/null
+++ b/packages/vue/src/useWorker/index.md
@@ -0,0 +1,227 @@
+
+
+# useWorker
+
+Reactive worker for multiprocessing.
+
+This composable provides a module to use complete and easy-to-use multiprocessing ⚡.
+
+NativeScript runs in the main thread, just like native applications do. We also have the Workers module available to allow processing in a thread other than the user interface. This allows us to keep the UI thread free to hold animations and touch events and any interactions without any blocking.
+
+This module facilitates the use of the workers module, launching the function that we pass to `useWorker` to a worker and thus keeping the main thread free for the user.
+
+This module is based on [@nativescript-use/nativescript-task](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-task).
+
+
+
+## Understanding how the module works and configuration
+
+With the default values this module will initialize a worker that will be available during the lifetime of the application, this is to save the worker startup time and launch the tasks to a worker that will always be available to execute tasks (in the documentation we will call it global worker or stickyWorker).
+
+Additionally, this module manages the use of the global worker and if it is in use by a task, it will send its tasks to another worker that will create and terminate when said task is finished.
+
+We can modify all this operation with the next configuration.
+
+```ts
+// app.ts | main.ts (entry file app)
+
+import { Task } from "@nativescript-use/vue";
+
+Task.globalWorkerConfig({
+ stickyWorker: true,
+ newWorkerIfGlobalIsUsed: true,
+ startGlobalWorker: true
+});
+
+// run app
+```
+
+- `stickyWorker` - default `true`: When set to true the plugin always keeps a worker running to launch your tasks to this worker. This saves time when launching the task since initializing a worker takes time, by default it is true to launch each task as quickly as possible. If set to false the plugin will initialize a worker and terminate each task.
+- `newWorkerIfGlobalIsUsed` - default `true`: When `stickyWorker` is true and we have a worker always running, if we launch a task and the main worker is running with another task, a new worker will be created to launch this task and not wait for the previous task to finish. If you disable this flag and launch another task while one is running, it will have to wait until it reaches the beginning of the queue.
+- `startGlobalWorker` - default `true`: Initialize the global worker when the configuration is set, it will be available when you launch your first task. If disabled, when the first task is launched it will have the worker creation delay.
+
+Note: when the worker execution time is mentioned we are talking about about 200ms (it is almost nothing). It's not much, but this plugin prioritizes speed, which is why we keep a `stickyWorker` always available.
+
+## Basic Usage
+
+```vue
+
+```
+## useWorker configuracion
+
+```ts
+{
+ state?: Ref | TState,
+ initialResult?: TResult,
+ runOnChangeState?: boolean,
+ attachToContextFunctions?: {},
+ inmediate?: boolean,
+ performance?: boolean,
+ on?: {
+ progressUpdate?: (update: { data: TUpdate }) => void
+ completed?: (data: TResult) => void,
+ error?: (error: string) => void,
+ }
+}
+```
+
+- `state`: data that will be passed to the context of the function to be executed.
+- `initialResult`: is the default reactive object `result` that will be returned when implementing the `useWorker` composable.
+- `runOnChangeState`: If set to true and `state` is Ref or Reactive the function will be executed with each change made to the object passed `state`.
+- `attachToContextFunctions`: allows adding functions external to the worker to the worker context. See [inline-functions](#inline-functions).
+- `inmediate`: If set to true the worker will run immediately.
+- `performance`: Utility to check how long a function takes outside the worker and inside it. Useful to check the function execution time and whether you should send this task to the background or not. Use this only in development mode.
+- `on:{ progressUpdate }`: Callback that we can invoke from the worker to send updates to the main thread before the worker has finished. See [onProgressUpdate](#onprogressupdate).
+- `on:{ completed }`: Callback that will be executed when the task has finished successfully.
+- `on:{ error }`: Callback that will be executed when the task has finished with an error.
+
+## Inline functions
+
+See `attachToContextFunctions` option.
+```vue
+
+```
+
+## `onProgressUpdate`
+
+See `onProgressUpdate` option and reactive `update`.
+```vue
+
+```
+
+## Using dependencies
+
+We need to define a worker with the imports that we want to have defined in our tasks. We define the file `globalWorker.ts|js` in the `src|app` folder of our project, import the modules that we want to have available and pass them to the `defineWorker` function that this library provides.
+
+```ts
+// /app/globalWorker.ts|js
+import '@nativescript/core/globals';
+import { defineWorker } from "@nativescript-use/vue";
+
+import { myUtils } from '@utils';
+import { otherLib } from 'other-lib';
+
+defineWorker({ imports: { myUtils, otherLib } });
+```
+
+Now access the modules defined in the globalWorker file from the context.
+```ts
+import { useWorker } from "@nativescript-use/vue";
+import { myUtils } from '@utils';
+import { otherLib } from 'other-lib';
+
+const { runTask, result } = useWorker((ctx) => {
+ return myUtils.someFunction(1000) + otherLib.otherFunction(ctx.state);
+}, { state: 100 })
+```
+
+## Source
+
+
+## Type declaration
+```ts
+import { Ref, ComputedRef } from "nativescript-vue";
+import { TaskFunc } from '@nativescript-use/nativescript-task';
+import { Ref, UnwrapRef, DeepReadonly } from 'nativescript-vue';
+export * from "@nativescript-use/nativescript-task";
+
+/**
+ * Reactive worker for multiprocessing.
+ */
+export declare function useWorker(fun: TaskFunc, TResult, TUpdate>, options?: {
+ state?: Ref | TState;
+ initialResult?: TResult;
+ runOnChangeState?: boolean;
+ attachToContextFunctions?: {};
+ inmediate?: boolean;
+ performance?: boolean;
+ on?: {
+ progressUpdate?: (update: {
+ data: TUpdate;
+ }) => void;
+ completed?: (data: TResult) => void;
+ error?: (error: string) => void;
+ };
+}): {
+ result: Readonly[>>>;
+ update: Readonly][ }>>;
+ isRunning: Readonly][>;
+ isFinish: Readonly][>;
+ error: Readonly][>;
+ runTask: (newData?: Ref] | TState) => void;
+};
+
+```
+
+## Core dependency
+[@nativescript-use/nativescript-task](https://github.com/NativeScript-Use/NativeScript-Use/tree/main/packages/nativescript-task)
\ No newline at end of file
diff --git a/packages/vue/src/useWorker/index.ts b/packages/vue/src/useWorker/index.ts
new file mode 100644
index 0000000..4408186
--- /dev/null
+++ b/packages/vue/src/useWorker/index.ts
@@ -0,0 +1,92 @@
+import { OnData, Task, TaskFunc } from '@nativescript-use/nativescript-task';
+import { Ref, UnwrapRef, isReactive, isRef, readonly, ref, shallowRef, unref, watch } from 'nativescript-vue';
+export * from '@nativescript-use/nativescript-task';
+
+/**
+ * Reactive worker for multiprocessing.
+ */
+export function useWorker(
+ vueFunction: TaskFunc, TResult, TUpdate>,
+ options?: {
+ state?: Ref | TState;
+ initialResult?: TResult;
+ runOnChangeState?: boolean;
+ attachToContextFunctions?: {};
+ inmediate?: boolean;
+ performance?: boolean;
+ on?: {
+ progressUpdate?: (update: { data: TUpdate }) => void;
+ completed?: (data: TResult) => void;
+ error?: (error: string) => void;
+ };
+ }
+) {
+ const { initialResult = null, runOnChangeState = false, inmediate = false, performance = false } = options ?? {};
+
+ let runningCount = 0;
+ const result = ref(initialResult);
+ const update = ref>();
+ const isRunning = shallowRef(false);
+ const isFinish = shallowRef(false);
+ const error = shallowRef(null);
+
+ if (runOnChangeState === true && options?.state && (isRef(options.state) || isReactive(options.state))) {
+ watch(options.state as Ref, runTask, { deep: true });
+ }
+
+ function runTask(newData?: Ref | TState) {
+ isRunning.value = true;
+ isFinish.value = false;
+ error.value = null;
+ runningCount++;
+
+ Task.start, TResult, TUpdate>(
+ (ctx) => {
+ return vueFunction(ctx);
+ },
+ {
+ state: (unref(newData) ?? unref(options?.state)) as UnwrapRef,
+ onProgressUpdate(updateData) {
+ update.value = updateData;
+ if (options?.on?.progressUpdate) {
+ options.on.progressUpdate(updateData);
+ }
+ },
+ attachToContextFunctions: { ...(options?.attachToContextFunctions ?? {}), ...{ vueFunction } },
+ performance,
+ }
+ )
+ .then((completed) => {
+ result.value = completed.data as UnwrapRef;
+ if (options?.on?.completed) {
+ options.on.completed(completed.data as TResult);
+ }
+ })
+ .catch((result) => {
+ error.value = JSON.stringify(result.error);
+ if (options?.on?.error) {
+ options.on.error(result.error);
+ }
+ })
+ .finally(() => {
+ runningCount--;
+
+ if (runningCount == 0) {
+ isRunning.value = false;
+ isFinish.value = true;
+ }
+ });
+ }
+ if (inmediate === true) {
+ runTask();
+ }
+
+ return {
+ result: readonly(result),
+ update: readonly(update),
+ isRunning: readonly(isRunning),
+ isFinish: readonly(isFinish),
+ error: readonly(error),
+ runTask,
+ };
+}
diff --git a/packages/vue/src/utils.ts b/packages/vue/src/utils.ts
new file mode 100644
index 0000000..8d914da
--- /dev/null
+++ b/packages/vue/src/utils.ts
@@ -0,0 +1,15 @@
+import { Utils } from '@nativescript/core';
+import { LOG_PREFIX } from './constant';
+
+export const warn = (text: any) => console.warn(`${LOG_PREFIX}${text}`);
+
+export function toDeviceIndependent(size: any /* CoreTypes.dip | CoreTypes.LengthDipUnit | CoreTypes.LengthPxUnit */) {
+ if (Utils.isNumber(size)) {
+ return size;
+ } else if (size?.unit) {
+ if (size.unit === 'dip') return size;
+ else if (size.unit === 'px') return Utils.layout.toDeviceIndependentPixels(size.value);
+ }
+ warn(`Impossible to extract the value in DPI`);
+ return size;
+}
diff --git a/packages/vue/started.md b/packages/vue/started.md
new file mode 100644
index 0000000..40e371d
--- /dev/null
+++ b/packages/vue/started.md
@@ -0,0 +1,17 @@
+# Get Started
+
+NativeScript-Use/Vue is based on [VueUse](https://vueuse.org/), it is a collection of utilities for [NativeScript-Vue3](https://github.com/nativescript-vue/nativescript-vue)
+
+Most of the [VueUse](https://vueuse.org/) functions work by default in NativeScript-Vue, only utilities that depend on the dom or web elements are the functions that don't work in NativeScript-Vue. In addition, this package adds specific functions for Vue in Native.
+
+## Installation
+
+
+
+```bash
+npm i @nativescript-use/vue
+```
+
+## Need a NativeScript-Vue3 Starter?
+Check out [Quick start section.](https://github.com/nativescript-vue/nativescript-vue#quick-start)
+
diff --git a/packages/vue/tsconfig.json b/packages/vue/tsconfig.json
new file mode 100644
index 0000000..7e14557
--- /dev/null
+++ b/packages/vue/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "rootDir": ".",
+ "paths": {
+ "@nativescript-use/nativescript-task": ["../nativescript-task"]
+ }
+ },
+ "exclude": ["**/*.spec.ts", "**/*.test.ts", "angular", "node_modules"],
+ "include": ["**/*.ts", "./src/**/*.ts", "references.d.ts"]
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..12a703d
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/scripts/copy-packages.ts b/scripts/copy-packages.ts
new file mode 100644
index 0000000..15f3d56
--- /dev/null
+++ b/scripts/copy-packages.ts
@@ -0,0 +1,25 @@
+import fs from 'fs';
+import path, { dirname } from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+console.log('Copying package.json files to dist');
+
+const packagePatchs = path.resolve(__dirname, '..', 'packages');
+const dist = path.resolve(__dirname, '..', 'dist', 'packages');
+
+const packages = fs.readdirSync(packagePatchs, { withFileTypes: true }).filter((dirent) => dirent.isDirectory());
+
+packages.forEach((dirent) => {
+ const packagePath = path.resolve(packagePatchs, dirent.name, 'package.json');
+ if (fs.existsSync(packagePath)) {
+ const distPackagePath = path.resolve(dist, dirent.name, 'package.json');
+
+ if (!fs.existsSync(distPackagePath)) {
+ fs.copyFileSync(packagePath, distPackagePath);
+ console.log(`Copied ${dirent.name} package.json`);
+ }
+ }
+});
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..4c8bf5f
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,12 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ['./packages/vue/.vitepress/theme/**/*.vue', './packages/vue/.vitepress/theme/*.js'],
+ theme: {
+ extend: {
+ colors: {
+ 'ns-vueuse': '#21cd80',
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/tools/demo/change-icon/index.ts b/tools/demo/change-icon/index.ts
new file mode 100644
index 0000000..0195d18
--- /dev/null
+++ b/tools/demo/change-icon/index.ts
@@ -0,0 +1,8 @@
+import { DemoSharedBase } from '../utils';
+import {} from '@nativescript-use/change-icon';
+
+export class DemoSharedChangeIcon extends DemoSharedBase {
+ testIt() {
+ console.log('test change-icon!');
+ }
+}
diff --git a/tools/demo/index.ts b/tools/demo/index.ts
index 95d5ae4..0c7bda8 100644
--- a/tools/demo/index.ts
+++ b/tools/demo/index.ts
@@ -1,5 +1,10 @@
export * from './utils';
+export * from './change-icon';
export * from './nativescript-clipboard';
+export * from './nativescript-intersection-observer';
export * from './nativescript-keyboard';
+export * from './nativescript-localstorage';
+export * from './nativescript-media-query';
export * from './nativescript-orientation';
-export * from './nativescript-vueuse';
+export * from './nativescript-task';
+export * from './vue';
diff --git a/tools/demo/nativescript-clipboard/index.ts b/tools/demo/nativescript-clipboard/index.ts
index a541fbb..99df490 100644
--- a/tools/demo/nativescript-clipboard/index.ts
+++ b/tools/demo/nativescript-clipboard/index.ts
@@ -1,9 +1,8 @@
import { DemoSharedBase } from '../utils';
-import { } from '@vallemar/nativescript-clipboard';
+import {} from '@nativescript-use/nativescript-clipboard';
export class DemoSharedNativescriptClipboard extends DemoSharedBase {
-
testIt() {
console.log('test nativescript-clipboard!');
}
-}
\ No newline at end of file
+}
diff --git a/tools/demo/nativescript-keyboard/index.ts b/tools/demo/nativescript-keyboard/index.ts
index 88079c7..1bcdc3c 100644
--- a/tools/demo/nativescript-keyboard/index.ts
+++ b/tools/demo/nativescript-keyboard/index.ts
@@ -1,9 +1,8 @@
import { DemoSharedBase } from '../utils';
-import { } from '@vallemar/nativescript-keyboard';
+import {} from '@nativescript-use/nativescript-keyboard';
export class DemoSharedNativescriptKeyboard extends DemoSharedBase {
-
testIt() {
console.log('test nativescript-keyboard!');
}
-}
\ No newline at end of file
+}
diff --git a/tools/demo/nativescript-localstorage/index.ts b/tools/demo/nativescript-localstorage/index.ts
new file mode 100644
index 0000000..9de2300
--- /dev/null
+++ b/tools/demo/nativescript-localstorage/index.ts
@@ -0,0 +1,8 @@
+import { DemoSharedBase } from '../utils';
+import {} from '@nativescript-use/nativescript-localstorage';
+
+export class DemoSharedNativescriptLocalstorage extends DemoSharedBase {
+ testIt() {
+ console.log('test nativescript-localstorage!');
+ }
+}
diff --git a/tools/demo/nativescript-media-query/index.ts b/tools/demo/nativescript-media-query/index.ts
new file mode 100644
index 0000000..0253a8b
--- /dev/null
+++ b/tools/demo/nativescript-media-query/index.ts
@@ -0,0 +1,8 @@
+import { DemoSharedBase } from '../utils';
+import {} from '@nativescript-use/nativescript-media-query';
+
+export class DemoSharedNativescriptMediaQuery extends DemoSharedBase {
+ testIt() {
+ console.log('test nativescript-media-query!');
+ }
+}
diff --git a/tools/demo/nativescript-orientation/index.ts b/tools/demo/nativescript-orientation/index.ts
index 5a67319..66dd746 100644
--- a/tools/demo/nativescript-orientation/index.ts
+++ b/tools/demo/nativescript-orientation/index.ts
@@ -1,9 +1,8 @@
import { DemoSharedBase } from '../utils';
-import { } from '@vallemar/nativescript-orientation';
+import {} from '@nativescript-use/nativescript-orientation';
export class DemoSharedNativescriptOrientation extends DemoSharedBase {
-
testIt() {
console.log('test nativescript-orientation!');
}
-}
\ No newline at end of file
+}
diff --git a/tools/demo/nativescript-task/index.ts b/tools/demo/nativescript-task/index.ts
new file mode 100644
index 0000000..a187914
--- /dev/null
+++ b/tools/demo/nativescript-task/index.ts
@@ -0,0 +1,8 @@
+import { DemoSharedBase } from '../utils';
+import {} from 'undefined/nativescript-task';
+
+export class DemoSharedNativescriptTask extends DemoSharedBase {
+ testIt() {
+ console.log('test nativescript-task!');
+ }
+}
diff --git a/tools/demo/nativescript-vueuse/index.ts b/tools/demo/nativescript-vueuse/index.ts
index d5f6cdb..ed3ce11 100644
--- a/tools/demo/nativescript-vueuse/index.ts
+++ b/tools/demo/nativescript-vueuse/index.ts
@@ -1,9 +1,8 @@
import { DemoSharedBase } from '../utils';
-import { } from '@vallemar/nativescript-vueuse';
+import {} from '@nativescript-use/vue';
export class DemoSharedNativescriptVueuse extends DemoSharedBase {
-
testIt() {
console.log('test nativescript-vueuse!');
}
-}
\ No newline at end of file
+}
diff --git a/tools/demo/tsconfig.json b/tools/demo/tsconfig.json
index ed2bcae..bdcc206 100644
--- a/tools/demo/tsconfig.json
+++ b/tools/demo/tsconfig.json
@@ -3,9 +3,8 @@
"compilerOptions": {
"baseUrl": ".",
"paths": {
- "@vallemar/*": [
- "../../packages/*"
- ]
+ "@/*": ["../../packages/*"],
+ "@nativescript-use/*": ["../../packages/*"]
}
}
}
diff --git a/tools/demo/vue/index.ts b/tools/demo/vue/index.ts
new file mode 100644
index 0000000..6896920
--- /dev/null
+++ b/tools/demo/vue/index.ts
@@ -0,0 +1,8 @@
+import { DemoSharedBase } from '../utils';
+import {} from '@nativescript-use/vue';
+
+export class DemoSharedVue extends DemoSharedBase {
+ testIt() {
+ console.log('test vue!');
+ }
+}
diff --git a/tools/package-settings.json b/tools/package-settings.json
index 7c28c58..f209b35 100644
--- a/tools/package-settings.json
+++ b/tools/package-settings.json
@@ -1,22 +1,16 @@
{
"repository": {
"type": "git",
- "url": "https://github.com/NativeScript/plugins.git"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use.git"
},
- "keywords": [
- "NativeScript",
- "JavaScript",
- "TypeScript",
- "iOS",
- "Android"
- ],
+ "keywords": ["NativeScript", "JavaScript", "TypeScript", "iOS", "Android"],
"author": {
- "name": "Juan de Dios Matínez Vallejo",
+ "name": "Juan de Dios Martínez Vallejo",
"email": "oss@nativescript.org"
},
"bugs": {
- "url": "https://github.com/NativeScript/plugins/issues"
+ "url": "https://github.com/NativeScript-Use/NativeScript-Use/issues"
},
"license": "Apache-2.0",
- "homepage": "https://github.com/NativeScript/plugins"
+ "homepage": "https://github.com/NativeScript-Use/NativeScript-Use"
}
diff --git a/tools/workspace-scripts.js b/tools/workspace-scripts.js
index ff4a44e..cd22a5d 100644
--- a/tools/workspace-scripts.js
+++ b/tools/workspace-scripts.js
@@ -17,63 +17,61 @@ module.exports = {
},
// demos
apps: {
- '...Vanilla...': {
- script: 'npx cowsay "Nothing wrong with vanilla 🍦"',
- description: ' 🔻 Vanilla',
- },
- demo: {
- clean: {
- script: 'nx run demo:clean',
- description: '⚆ Clean 🧹',
- },
- ios: {
- script: 'nx run demo:ios',
- description: '⚆ Run iOS ',
- },
- android: {
- script: 'nx run demo:android',
- description: '⚆ Run Android 🤖',
- },
- },
- '...Angular...': {
- script: 'npx cowsay "Test all the Angles!"',
- description: ' 🔻 Angular',
- },
- 'demo-angular': {
- clean: {
- script: 'nx run demo-angular:clean',
- description: '⚆ Clean 🧹',
- },
- ios: {
- script: 'nx run demo-angular:ios',
- description: '⚆ Run iOS ',
- },
- android: {
- script: 'nx run demo-angular:android',
- description: '⚆ Run Android 🤖',
- },
- },
-
-
- '...Vue...': {
- script: 'npx cowsay "You like the vue here..."',
- description: ' 🔻 Vue',
- },
- 'demo-vue': {
- clean: {
- script: 'nx run demo-vue:clean',
- description: '⚆ Clean 🧹',
- },
- ios: {
- script: 'nx run demo-vue:ios',
- description: '⚆ Run iOS ',
- },
- android: {
- script: 'nx run demo-vue:android',
- description: '⚆ Run Android 🤖',
+ '...Vanilla...': {
+ script: 'npx cowsay "Nothing wrong with vanilla 🍦"',
+ description: ' 🔻 Vanilla',
+ },
+ demo: {
+ clean: {
+ script: 'nx run demo:clean',
+ description: '⚆ Clean 🧹',
+ },
+ ios: {
+ script: 'nx run demo:ios',
+ description: '⚆ Run iOS ',
+ },
+ android: {
+ script: 'nx run demo:android',
+ description: '⚆ Run Android 🤖',
+ },
+ },
+ '...Angular...': {
+ script: 'npx cowsay "Test all the Angles!"',
+ description: ' 🔻 Angular',
+ },
+ 'demo-angular': {
+ clean: {
+ script: 'nx run demo-angular:clean',
+ description: '⚆ Clean 🧹',
+ },
+ ios: {
+ script: 'nx run demo-angular:ios',
+ description: '⚆ Run iOS ',
+ },
+ android: {
+ script: 'nx run demo-angular:android',
+ description: '⚆ Run Android 🤖',
+ },
+ },
+ '...React...': {
+ script: 'npx cowsay "You like your TS with an X..."',
+ description: ' 🔻 React',
+ },
+ 'demo-react': {
+ clean: {
+ script: 'nx run demo-react:clean',
+ description: '⚆ Clean 🧹',
+ },
+ ios: {
+ script: 'nx run demo-react:ios',
+ description: '⚆ Run iOS ',
+ },
+ android: {
+ script: 'nx run demo-react:android',
+ description: '⚆ Run Android 🤖',
+ },
+ },
},
- },
- },
'⚙️': {
script: `npx cowsay "@vallemar/* packages will keep your ⚙️ cranking"`,
@@ -81,36 +79,71 @@ module.exports = {
},
// packages
// build output is always in dist/packages
- '@vallemar': {
- // @vallemar/nativescript-vueuse
- 'nativescript-vueuse': {
- build: {
- script: 'nx run nativescript-vueuse:build.all',
- description: '@vallemar/nativescript-vueuse: Build',
- },
- },
- // @vallemar/nativescript-orientation
- 'nativescript-orientation': {
- build: {
- script: 'nx run nativescript-orientation:build.all',
- description: '@vallemar/nativescript-orientation: Build',
- },
- },
- // @vallemar/nativescript-keyboard
- 'nativescript-keyboard': {
- build: {
- script: 'nx run nativescript-keyboard:build.all',
- description: '@vallemar/nativescript-keyboard: Build',
- },
- },
- // @vallemar/nativescript-clipboard
- 'nativescript-clipboard': {
- build: {
- script: 'nx run nativescript-clipboard:build.all',
- description: '@vallemar/nativescript-clipboard: Build',
- },
- },
- 'build-all': {
+ '@nativescript-use': {
+ // @nativescript-use/vue
+ vue: {
+ build: {
+ script: 'nx run vue:build.all',
+ description: '@nativescript-use/vue: Build',
+ },
+ },
+ // @vallemar/nativescript-orientation
+ 'nativescript-orientation': {
+ build: {
+ script: 'nx run nativescript-orientation:build.all',
+ description: '@nativescript-use/nativescript-orientation: Build',
+ },
+ },
+ // @vallemar/nativescript-keyboard
+ 'nativescript-keyboard': {
+ build: {
+ script: 'nx run nativescript-keyboard:build.all',
+ description: '@nativescript-use/nativescript-keyboard: Build',
+ },
+ },
+ // @vallemar/nativescript-clipboard
+ 'nativescript-clipboard': {
+ build: {
+ script: 'nx run nativescript-clipboard:build.all',
+ description: '@nativescript-use/nativescript-clipboard: Build',
+ },
+ },
+ // @nativescript-use/nativescript-media-query
+ 'nativescript-media-query': {
+ build: {
+ script: 'nx run nativescript-media-query:build.all',
+ description: '@nativescript-use/nativescript-media-query: Build',
+ },
+ },
+ // @nativescript-use/nativescript-intersection-observer
+ 'nativescript-intersection-observer': {
+ build: {
+ script: 'nx run nativescript-intersection-observer:build.all',
+ description: '@nativescript-use/nativescript-intersection-observer: Build',
+ },
+ },
+ // @nativescript-use/nativescript-task
+ 'nativescript-task': {
+ build: {
+ script: 'nx run nativescript-task:build.all',
+ description: '@nativescript-use/nativescript-task: Build',
+ },
+ },
+ // @nativescript-use/change-icon
+ 'change-icon': {
+ build: {
+ script: 'nx run change-icon:build.all',
+ description: '@nativescript-use/change-icon: Build',
+ },
+ },
+ // @nativescript-use/nativescript-localstorage
+ 'nativescript-localstorage': {
+ build: {
+ script: 'nx run nativescript-localstorage:build.all',
+ description: '@nativescript-use/nativescript-localstorage: Build',
+ },
+ },
+ 'build-all': {
script: 'nx run-many --target=build.all --all',
description: 'Build all packages',
},
@@ -120,24 +153,44 @@ module.exports = {
description: '_____________ Focus (VS Code supported) _____________',
},
focus: {
- 'nativescript-vueuse': {
- script: 'nx run nativescript-vueuse:focus',
- description: 'Focus on @vallemar/nativescript-vueuse',
- },
- 'nativescript-orientation': {
- script: 'nx run nativescript-orientation:focus',
- description: 'Focus on @vallemar/nativescript-orientation',
- },
- 'nativescript-keyboard': {
- script: 'nx run nativescript-keyboard:focus',
- description: 'Focus on @vallemar/nativescript-keyboard',
- },
- 'nativescript-clipboard': {
- script: 'nx run nativescript-clipboard:focus',
- description: 'Focus on @vallemar/nativescript-clipboard',
- },
- reset: {
- script: 'nx g @vallemar/plugin-tools:focus-packages',
+ vue: {
+ script: 'nx run vue:focus',
+ description: 'Focus on @nativescript-use/vue',
+ },
+ 'nativescript-orientation': {
+ script: 'nx run nativescript-orientation:focus',
+ description: 'Focus on @nativescript-use/nativescript-orientation',
+ },
+ 'nativescript-keyboard': {
+ script: 'nx run nativescript-keyboard:focus',
+ description: 'Focus on @nativescript-use/nativescript-keyboard',
+ },
+ 'nativescript-clipboard': {
+ script: 'nx run nativescript-clipboard:focus',
+ description: 'Focus on @nativescript-use/nativescript-clipboard',
+ },
+ 'nativescript-media-query': {
+ script: 'nx run nativescript-media-query:focus',
+ description: 'Focus on @nativescript-use/nativescript-media-query',
+ },
+ 'nativescript-intersection-observer': {
+ script: 'nx run nativescript-intersection-observer:focus',
+ description: 'Focus on @nativescript-use/nativescript-intersection-observer',
+ },
+ 'nativescript-task': {
+ script: 'nx run nativescript-task:focus',
+ description: 'Focus on @nativescript-use/nativescript-task',
+ },
+ 'change-icon': {
+ script: 'nx run change-icon:focus',
+ description: 'Focus on @nativescript-use/change-icon',
+ },
+ 'nativescript-localstorage': {
+ script: 'nx run nativescript-localstorage:focus',
+ description: 'Focus on @nativescript-use/nativescript-localstorage',
+ },
+ reset: {
+ script: 'nx g @nativescript-use/plugin-tools:focus-packages',
description: 'Reset Focus',
},
},
diff --git a/tsconfig.base.json b/tsconfig.base.json
index dcc8787..6e51dbc 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -9,10 +9,7 @@
"noEmitHelpers": true,
"target": "ES2020",
"module": "ESNext",
- "lib": [
- "ESNext",
- "dom"
- ],
+ "lib": ["ESNext", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
@@ -23,29 +20,23 @@
}
],
"paths": {
-
- "@demo/shared": [
- "tools/demo/index.ts"
- ],
- "@vallemar/*": [
- "packages/*"
- ],
- "@vallemar/nativescript-vueuse": [
- "packages/nativescript-vueuse/index.d.ts"
- ],
- "@vallemar/nativescript-orientation": [
- "packages/nativescript-orientation/index.d.ts"
- ],
- "@vallemar/nativescript-keyboard": [
- "packages/nativescript-keyboard/index.d.ts"
- ],
- "@vallemar/nativescript-clipboard": [
- "packages/nativescript-clipboard/index.d.ts"
- ]
- }
+ "@demo/shared": ["tools/demo/index.ts"],
+ "@nativescript/core/*": ["node_modudes/@nativescript/core/*"],
+ "nativescript-vue": ["node_modudes/nativescript-vue/dist/index.d.ts"],
+ "nativescript-vue/*": ["node_modudes/nativescript-vue/dist/*"],
+ "@nativescript-use/*": ["packages/*"],
+ "@nativescript-use/vue": ["packages/vue/index.d.ts"],
+ "@nativescript-use/nativescript-orientation": ["packages/nativescript-orientation/index.d.ts"],
+ "@nativescript-use/nativescript-keyboard": ["packages/nativescript-keyboard/index.d.ts"],
+ "@nativescript-use/nativescript-clipboard": ["packages/nativescript-clipboard/index.d.ts"],
+ "@/*": ["packages/*"],
+ "@nativescript-use/nativescript-media-query": ["packages/nativescript-media-query/index.d.ts"],
+ "@nativescript-use/nativescript-intersection-observer": ["packages/nativescript-intersection-observer/index.d.ts"],
+ "@nativescript-use/nativescript-task": ["packages/nativescript-task/index.d.ts"],
+ "@nativescript-use/change-icon": ["packages/change-icon/index.d.ts"],
+ "@nativescript-use/nativescript-localstorage": ["packages/nativescript-localstorage/index.d.ts"]
+ },
+ "jsx": "react"
},
- "exclude": [
- "node_modules",
- "tmp"
- ]
+ "exclude": ["node_modules", "/packages/vue/node_modules", "tmp"]
}