mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-09-22 21:30:44 +02:00
refactor(geolocation): simplify API, defer permission checks (#1773)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"geolocation": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
No longer request permission automatically and leave to the user how to handle the `checkPermissions` and `requestPermissions` APIs.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"geolocation-js": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Update API to match other plugins.
|
||||||
+7
-1
@@ -26,9 +26,15 @@ target/
|
|||||||
# compiled plugins
|
# compiled plugins
|
||||||
dist-js/
|
dist-js/
|
||||||
|
|
||||||
# plugins .tauri director
|
# plugins .tauri directory
|
||||||
/plugins/*/.tauri
|
/plugins/*/.tauri
|
||||||
|
|
||||||
|
# examples
|
||||||
|
examples/*/dist
|
||||||
|
plugins/*/examples/*/dist
|
||||||
|
examples/*/src-tauri/gen/schemas
|
||||||
|
plugins/*/examples/*/src-tauri/gen/schemas
|
||||||
|
|
||||||
# logs
|
# logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -24,3 +24,4 @@ CHANGELOG.md
|
|||||||
# mobile build
|
# mobile build
|
||||||
**/ios/.build
|
**/ios/.build
|
||||||
**/.tauri
|
**/.tauri
|
||||||
|
plugins/*/android/build
|
||||||
|
|||||||
Generated
+2
@@ -231,7 +231,9 @@ dependencies = [
|
|||||||
"tauri-plugin-clipboard-manager",
|
"tauri-plugin-clipboard-manager",
|
||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
"tauri-plugin-fs",
|
"tauri-plugin-fs",
|
||||||
|
"tauri-plugin-geolocation",
|
||||||
"tauri-plugin-global-shortcut",
|
"tauri-plugin-global-shortcut",
|
||||||
|
"tauri-plugin-haptics",
|
||||||
"tauri-plugin-http",
|
"tauri-plugin-http",
|
||||||
"tauri-plugin-log",
|
"tauri-plugin-log",
|
||||||
"tauri-plugin-nfc",
|
"tauri-plugin-nfc",
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
/dist/*
|
|
||||||
!/dist/.gitkeep
|
|
||||||
Vendored
@@ -16,7 +16,9 @@
|
|||||||
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.2",
|
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.2",
|
||||||
"@tauri-apps/plugin-dialog": "2.0.0-rc.1",
|
"@tauri-apps/plugin-dialog": "2.0.0-rc.1",
|
||||||
"@tauri-apps/plugin-fs": "2.0.0-rc.2",
|
"@tauri-apps/plugin-fs": "2.0.0-rc.2",
|
||||||
|
"@tauri-apps/plugin-geolocation": "2.0.0-rc.1",
|
||||||
"@tauri-apps/plugin-global-shortcut": "2.0.0-rc.1",
|
"@tauri-apps/plugin-global-shortcut": "2.0.0-rc.1",
|
||||||
|
"@tauri-apps/plugin-haptics": "2.0.0-rc.1",
|
||||||
"@tauri-apps/plugin-http": "2.0.0-rc.2",
|
"@tauri-apps/plugin-http": "2.0.0-rc.2",
|
||||||
"@tauri-apps/plugin-nfc": "2.0.0-rc.1",
|
"@tauri-apps/plugin-nfc": "2.0.0-rc.1",
|
||||||
"@tauri-apps/plugin-notification": "2.0.0-rc.1",
|
"@tauri-apps/plugin-notification": "2.0.0-rc.1",
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ tauri-plugin-window-state = { path = "../../../plugins/window-state", version =
|
|||||||
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-rc.4" }
|
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-rc.4" }
|
||||||
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.0.0-rc.3" }
|
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.0.0-rc.3" }
|
||||||
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.0.0-rc.3" }
|
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.0.0-rc.3" }
|
||||||
|
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.0.0-rc.3" }
|
||||||
|
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.0.0-rc.3" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
prod = ["tauri/custom-protocol"]
|
prod = ["tauri/custom-protocol"]
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
"barcode-scanner:allow-scan",
|
"barcode-scanner:allow-scan",
|
||||||
"barcode-scanner:allow-cancel",
|
"barcode-scanner:allow-cancel",
|
||||||
"barcode-scanner:allow-request-permissions",
|
"barcode-scanner:allow-request-permissions",
|
||||||
"barcode-scanner:allow-check-permissions"
|
"barcode-scanner:allow-check-permissions",
|
||||||
|
"geolocation:allow-check-permissions",
|
||||||
|
"geolocation:allow-request-permissions",
|
||||||
|
"geolocation:allow-watch-position",
|
||||||
|
"geolocation:allow-get-current-position"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,8 @@ pub fn run() {
|
|||||||
app.handle().plugin(tauri_plugin_barcode_scanner::init())?;
|
app.handle().plugin(tauri_plugin_barcode_scanner::init())?;
|
||||||
app.handle().plugin(tauri_plugin_nfc::init())?;
|
app.handle().plugin(tauri_plugin_nfc::init())?;
|
||||||
app.handle().plugin(tauri_plugin_biometric::init())?;
|
app.handle().plugin(tauri_plugin_biometric::init())?;
|
||||||
|
app.handle().plugin(tauri_plugin_geolocation::init())?;
|
||||||
|
app.handle().plugin(tauri_plugin_haptics::init())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut webview_window_builder =
|
let mut webview_window_builder =
|
||||||
|
|||||||
+168
-165
@@ -1,203 +1,208 @@
|
|||||||
<script>
|
<script>
|
||||||
import { writable } from "svelte/store";
|
import { writable } from 'svelte/store'
|
||||||
import { open } from "@tauri-apps/plugin-shell";
|
import { open } from '@tauri-apps/plugin-shell'
|
||||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
import { getCurrentWebview } from "@tauri-apps/api/webview";
|
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||||
import * as os from "@tauri-apps/plugin-os";
|
import * as os from '@tauri-apps/plugin-os'
|
||||||
|
|
||||||
import Welcome from "./views/Welcome.svelte";
|
import Welcome from './views/Welcome.svelte'
|
||||||
import Cli from "./views/Cli.svelte";
|
import Cli from './views/Cli.svelte'
|
||||||
import Communication from "./views/Communication.svelte";
|
import Communication from './views/Communication.svelte'
|
||||||
import Dialog from "./views/Dialog.svelte";
|
import Dialog from './views/Dialog.svelte'
|
||||||
import FileSystem from "./views/FileSystem.svelte";
|
import FileSystem from './views/FileSystem.svelte'
|
||||||
import Http from "./views/Http.svelte";
|
import Http from './views/Http.svelte'
|
||||||
import Notifications from "./views/Notifications.svelte";
|
import Notifications from './views/Notifications.svelte'
|
||||||
import Shortcuts from "./views/Shortcuts.svelte";
|
import Shortcuts from './views/Shortcuts.svelte'
|
||||||
import Shell from "./views/Shell.svelte";
|
import Shell from './views/Shell.svelte'
|
||||||
import Store from "./views/Store.svelte";
|
import Store from './views/Store.svelte'
|
||||||
import Updater from "./views/Updater.svelte";
|
import Updater from './views/Updater.svelte'
|
||||||
import Clipboard from "./views/Clipboard.svelte";
|
import Clipboard from './views/Clipboard.svelte'
|
||||||
import WebRTC from "./views/WebRTC.svelte";
|
import WebRTC from './views/WebRTC.svelte'
|
||||||
import Scanner from "./views/Scanner.svelte";
|
import Scanner from './views/Scanner.svelte'
|
||||||
import Biometric from "./views/Biometric.svelte";
|
import Biometric from './views/Biometric.svelte'
|
||||||
|
import Geolocation from './views/Geolocation.svelte'
|
||||||
|
|
||||||
import { onMount, tick } from "svelte";
|
import { onMount, tick } from 'svelte'
|
||||||
import { ask } from "@tauri-apps/plugin-dialog";
|
import { ask } from '@tauri-apps/plugin-dialog'
|
||||||
import Nfc from "./views/Nfc.svelte";
|
import Nfc from './views/Nfc.svelte'
|
||||||
|
|
||||||
const appWindow = getCurrentWindow();
|
const appWindow = getCurrentWindow()
|
||||||
|
|
||||||
if (appWindow.label !== "main") {
|
if (appWindow.label !== 'main') {
|
||||||
appWindow.onCloseRequested(async (event) => {
|
appWindow.onCloseRequested(async (event) => {
|
||||||
const confirmed = await confirm("Are you sure?");
|
const confirmed = await confirm('Are you sure?')
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
// user did not confirm closing the window; let's prevent it
|
// user did not confirm closing the window; let's prevent it
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentWebview().onDragDropEvent((event) => {
|
getCurrentWebview().onDragDropEvent((event) => {
|
||||||
onMessage(`File drop: ${JSON.stringify(event.payload)}`);
|
onMessage(`File drop: ${JSON.stringify(event.payload)}`)
|
||||||
});
|
})
|
||||||
|
|
||||||
const userAgent = navigator.userAgent.toLowerCase();
|
const userAgent = navigator.userAgent.toLowerCase()
|
||||||
const isMobile =
|
const isMobile = userAgent.includes('android') || userAgent.includes('iphone')
|
||||||
userAgent.includes("android") || userAgent.includes("iphone");
|
|
||||||
|
|
||||||
const views = [
|
const views = [
|
||||||
{
|
{
|
||||||
label: "Welcome",
|
label: 'Welcome',
|
||||||
component: Welcome,
|
component: Welcome,
|
||||||
icon: "i-ph-hand-waving",
|
icon: 'i-ph-hand-waving'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Communication",
|
label: 'Communication',
|
||||||
component: Communication,
|
component: Communication,
|
||||||
icon: "i-codicon-radio-tower",
|
icon: 'i-codicon-radio-tower'
|
||||||
},
|
},
|
||||||
!isMobile && {
|
!isMobile && {
|
||||||
label: "CLI",
|
label: 'CLI',
|
||||||
component: Cli,
|
component: Cli,
|
||||||
icon: "i-codicon-terminal",
|
icon: 'i-codicon-terminal'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Dialog",
|
label: 'Dialog',
|
||||||
component: Dialog,
|
component: Dialog,
|
||||||
icon: "i-codicon-multiple-windows",
|
icon: 'i-codicon-multiple-windows'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "File system",
|
label: 'File system',
|
||||||
component: FileSystem,
|
component: FileSystem,
|
||||||
icon: "i-codicon-files",
|
icon: 'i-codicon-files'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "HTTP",
|
label: 'HTTP',
|
||||||
component: Http,
|
component: Http,
|
||||||
icon: "i-ph-globe-hemisphere-west",
|
icon: 'i-ph-globe-hemisphere-west'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Notifications",
|
label: 'Notifications',
|
||||||
component: Notifications,
|
component: Notifications,
|
||||||
icon: "i-codicon-bell-dot",
|
icon: 'i-codicon-bell-dot'
|
||||||
},
|
},
|
||||||
!isMobile && {
|
!isMobile && {
|
||||||
label: "Shortcuts",
|
label: 'Shortcuts',
|
||||||
component: Shortcuts,
|
component: Shortcuts,
|
||||||
icon: "i-codicon-record-keys",
|
icon: 'i-codicon-record-keys'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Shell",
|
label: 'Shell',
|
||||||
component: Shell,
|
component: Shell,
|
||||||
icon: "i-codicon-terminal-bash",
|
icon: 'i-codicon-terminal-bash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Store",
|
label: 'Store',
|
||||||
component: Store,
|
component: Store,
|
||||||
icon: "i-codicon-file-code",
|
icon: 'i-codicon-file-code'
|
||||||
},
|
},
|
||||||
!isMobile && {
|
!isMobile && {
|
||||||
label: "Updater",
|
label: 'Updater',
|
||||||
component: Updater,
|
component: Updater,
|
||||||
icon: "i-codicon-cloud-download",
|
icon: 'i-codicon-cloud-download'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Clipboard",
|
label: 'Clipboard',
|
||||||
component: Clipboard,
|
component: Clipboard,
|
||||||
icon: "i-codicon-clippy",
|
icon: 'i-codicon-clippy'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "WebRTC",
|
label: 'WebRTC',
|
||||||
component: WebRTC,
|
component: WebRTC,
|
||||||
icon: "i-ph-broadcast",
|
icon: 'i-ph-broadcast'
|
||||||
},
|
},
|
||||||
isMobile && {
|
isMobile && {
|
||||||
label: "Scanner",
|
label: 'Scanner',
|
||||||
component: Scanner,
|
component: Scanner,
|
||||||
icon: "i-ph-scan",
|
icon: 'i-ph-scan'
|
||||||
},
|
},
|
||||||
isMobile && {
|
isMobile && {
|
||||||
label: "NFC",
|
label: 'NFC',
|
||||||
component: Nfc,
|
component: Nfc,
|
||||||
icon: "i-ph-nfc",
|
icon: 'i-ph-nfc'
|
||||||
},
|
},
|
||||||
isMobile && {
|
isMobile && {
|
||||||
label: "Biometric",
|
label: 'Biometric',
|
||||||
component: Biometric,
|
component: Biometric,
|
||||||
icon: "i-ph-scan",
|
icon: 'i-ph-scan'
|
||||||
},
|
},
|
||||||
];
|
isMobile && {
|
||||||
|
label: 'Geolocation',
|
||||||
|
component: Geolocation,
|
||||||
|
icon: 'i-ph-map-pin'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
let selected = views[0];
|
let selected = views[0]
|
||||||
function select(view) {
|
function select(view) {
|
||||||
selected = view;
|
selected = view
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window controls
|
// Window controls
|
||||||
let isWindowMaximized;
|
let isWindowMaximized
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
isWindowMaximized = await appWindow.isMaximized();
|
isWindowMaximized = await appWindow.isMaximized()
|
||||||
appWindow.onResized(async () => {
|
appWindow.onResized(async () => {
|
||||||
isWindowMaximized = await appWindow.isMaximized();
|
isWindowMaximized = await appWindow.isMaximized()
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
function minimize() {
|
function minimize() {
|
||||||
appWindow.minimize();
|
appWindow.minimize()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleMaximize() {
|
async function toggleMaximize() {
|
||||||
(await appWindow.isMaximized())
|
;(await appWindow.isMaximized())
|
||||||
? appWindow.unmaximize()
|
? appWindow.unmaximize()
|
||||||
: appWindow.maximize();
|
: appWindow.maximize()
|
||||||
}
|
}
|
||||||
|
|
||||||
let confirmed_close = false;
|
let confirmed_close = false
|
||||||
async function close() {
|
async function close() {
|
||||||
if (!confirmed_close) {
|
if (!confirmed_close) {
|
||||||
confirmed_close = await ask(
|
confirmed_close = await ask(
|
||||||
"Are you sure that you want to close this window?",
|
'Are you sure that you want to close this window?',
|
||||||
{
|
{
|
||||||
title: "Tauri API",
|
title: 'Tauri API'
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (confirmed_close) {
|
if (confirmed_close) {
|
||||||
appWindow.close();
|
appWindow.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dark/light
|
// dark/light
|
||||||
let isDark;
|
let isDark
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
isDark = localStorage && localStorage.getItem("theme") == "dark";
|
isDark = localStorage && localStorage.getItem('theme') == 'dark'
|
||||||
applyTheme(isDark);
|
applyTheme(isDark)
|
||||||
});
|
})
|
||||||
function applyTheme(isDark) {
|
function applyTheme(isDark) {
|
||||||
const html = document.querySelector("html");
|
const html = document.querySelector('html')
|
||||||
isDark ? html.classList.add("dark") : html.classList.remove("dark");
|
isDark ? html.classList.add('dark') : html.classList.remove('dark')
|
||||||
localStorage && localStorage.setItem("theme", isDark ? "dark" : "");
|
localStorage && localStorage.setItem('theme', isDark ? 'dark' : '')
|
||||||
}
|
}
|
||||||
function toggleDark() {
|
function toggleDark() {
|
||||||
isDark = !isDark;
|
isDark = !isDark
|
||||||
applyTheme(isDark);
|
applyTheme(isDark)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console
|
// Console
|
||||||
let messages = writable([]);
|
let messages = writable([])
|
||||||
let consoleTextEl;
|
let consoleTextEl
|
||||||
async function onMessage(value) {
|
async function onMessage(value) {
|
||||||
messages.update((r) => [
|
messages.update((r) => [
|
||||||
...r,
|
...r,
|
||||||
{
|
{
|
||||||
html:
|
html:
|
||||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
||||||
(typeof value === "string" ? value : JSON.stringify(value, null, 1)) +
|
(typeof value === 'string' ? value : JSON.stringify(value, null, 1)) +
|
||||||
"</pre>",
|
'</pre>'
|
||||||
},
|
}
|
||||||
]);
|
])
|
||||||
await tick();
|
await tick()
|
||||||
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight;
|
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is renders HTML without sanitizing it so it's insecure
|
// this function is renders HTML without sanitizing it so it's insecure
|
||||||
@@ -209,111 +214,109 @@
|
|||||||
html:
|
html:
|
||||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
||||||
html +
|
html +
|
||||||
"</pre>",
|
'</pre>'
|
||||||
},
|
}
|
||||||
]);
|
])
|
||||||
await tick();
|
await tick()
|
||||||
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight;
|
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
messages.update(() => []);
|
messages.update(() => [])
|
||||||
}
|
}
|
||||||
|
|
||||||
let consoleEl, consoleH, cStartY;
|
let consoleEl, consoleH, cStartY
|
||||||
let minConsoleHeight = 50;
|
let minConsoleHeight = 50
|
||||||
function startResizingConsole(e) {
|
function startResizingConsole(e) {
|
||||||
cStartY = e.clientY;
|
cStartY = e.clientY
|
||||||
|
|
||||||
const styles = window.getComputedStyle(consoleEl);
|
const styles = window.getComputedStyle(consoleEl)
|
||||||
consoleH = parseInt(styles.height, 10);
|
consoleH = parseInt(styles.height, 10)
|
||||||
|
|
||||||
const moveHandler = (e) => {
|
const moveHandler = (e) => {
|
||||||
const dy = e.clientY - cStartY;
|
const dy = e.clientY - cStartY
|
||||||
const newH = consoleH - dy;
|
const newH = consoleH - dy
|
||||||
consoleEl.style.height = `${
|
consoleEl.style.height = `${
|
||||||
newH < minConsoleHeight ? minConsoleHeight : newH
|
newH < minConsoleHeight ? minConsoleHeight : newH
|
||||||
}px`;
|
}px`
|
||||||
};
|
}
|
||||||
const upHandler = () => {
|
const upHandler = () => {
|
||||||
document.removeEventListener("mouseup", upHandler);
|
document.removeEventListener('mouseup', upHandler)
|
||||||
document.removeEventListener("mousemove", moveHandler);
|
document.removeEventListener('mousemove', moveHandler)
|
||||||
};
|
}
|
||||||
document.addEventListener("mouseup", upHandler);
|
document.addEventListener('mouseup', upHandler)
|
||||||
document.addEventListener("mousemove", moveHandler);
|
document.addEventListener('mousemove', moveHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
let isWindows;
|
let isWindows
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
isWindows = (await os.platform()) === "windows";
|
isWindows = (await os.platform()) === 'windows'
|
||||||
});
|
})
|
||||||
|
|
||||||
// mobile
|
// mobile
|
||||||
let isSideBarOpen = false;
|
let isSideBarOpen = false
|
||||||
let sidebar;
|
let sidebar
|
||||||
let sidebarToggle;
|
let sidebarToggle
|
||||||
let isDraggingSideBar = false;
|
let isDraggingSideBar = false
|
||||||
let draggingStartPosX = 0;
|
let draggingStartPosX = 0
|
||||||
let draggingEndPosX = 0;
|
let draggingEndPosX = 0
|
||||||
const clamp = (min, num, max) => Math.min(Math.max(num, min), max);
|
const clamp = (min, num, max) => Math.min(Math.max(num, min), max)
|
||||||
|
|
||||||
function toggleSidebar(sidebar, isSideBarOpen) {
|
function toggleSidebar(sidebar, isSideBarOpen) {
|
||||||
sidebar.style.setProperty(
|
sidebar.style.setProperty(
|
||||||
"--translate-x",
|
'--translate-x',
|
||||||
`${isSideBarOpen ? "0" : "-18.75"}rem`
|
`${isSideBarOpen ? '0' : '-18.75'}rem`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
sidebar = document.querySelector("#sidebar");
|
sidebar = document.querySelector('#sidebar')
|
||||||
sidebarToggle = document.querySelector("#sidebarToggle");
|
sidebarToggle = document.querySelector('#sidebarToggle')
|
||||||
|
|
||||||
document.addEventListener("click", (e) => {
|
document.addEventListener('click', (e) => {
|
||||||
if (sidebarToggle.contains(e.target)) {
|
if (sidebarToggle.contains(e.target)) {
|
||||||
isSideBarOpen = !isSideBarOpen;
|
isSideBarOpen = !isSideBarOpen
|
||||||
} else if (isSideBarOpen && !sidebar.contains(e.target)) {
|
} else if (isSideBarOpen && !sidebar.contains(e.target)) {
|
||||||
isSideBarOpen = false;
|
isSideBarOpen = false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
document.addEventListener("touchstart", (e) => {
|
document.addEventListener('touchstart', (e) => {
|
||||||
if (sidebarToggle.contains(e.target)) return;
|
if (sidebarToggle.contains(e.target)) return
|
||||||
|
|
||||||
const x = e.touches[0].clientX;
|
const x = e.touches[0].clientX
|
||||||
if ((0 < x && x < 20 && !isSideBarOpen) || isSideBarOpen) {
|
if ((0 < x && x < 20 && !isSideBarOpen) || isSideBarOpen) {
|
||||||
isDraggingSideBar = true;
|
isDraggingSideBar = true
|
||||||
draggingStartPosX = x;
|
draggingStartPosX = x
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
document.addEventListener("touchmove", (e) => {
|
document.addEventListener('touchmove', (e) => {
|
||||||
if (isDraggingSideBar) {
|
if (isDraggingSideBar) {
|
||||||
const x = e.touches[0].clientX;
|
const x = e.touches[0].clientX
|
||||||
draggingEndPosX = x;
|
draggingEndPosX = x
|
||||||
const delta = (x - draggingStartPosX) / 10;
|
const delta = (x - draggingStartPosX) / 10
|
||||||
sidebar.style.setProperty(
|
sidebar.style.setProperty(
|
||||||
"--translate-x",
|
'--translate-x',
|
||||||
`-${clamp(0, isSideBarOpen ? 0 - delta : 18.75 - delta, 18.75)}rem`
|
`-${clamp(0, isSideBarOpen ? 0 - delta : 18.75 - delta, 18.75)}rem`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
document.addEventListener("touchend", () => {
|
document.addEventListener('touchend', () => {
|
||||||
if (isDraggingSideBar) {
|
if (isDraggingSideBar) {
|
||||||
const delta = (draggingEndPosX - draggingStartPosX) / 10;
|
const delta = (draggingEndPosX - draggingStartPosX) / 10
|
||||||
isSideBarOpen = isSideBarOpen
|
isSideBarOpen = isSideBarOpen ? delta > -(18.75 / 2) : delta > 18.75 / 2
|
||||||
? delta > -(18.75 / 2)
|
|
||||||
: delta > 18.75 / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isDraggingSideBar = false;
|
isDraggingSideBar = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
const sidebar = document.querySelector("#sidebar");
|
const sidebar = document.querySelector('#sidebar')
|
||||||
if (sidebar) {
|
if (sidebar) {
|
||||||
toggleSidebar(sidebar, isSideBarOpen);
|
toggleSidebar(sidebar, isSideBarOpen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -332,7 +335,7 @@
|
|||||||
children:items-center children:justify-center"
|
children:items-center children:justify-center"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
title={isDark ? "Switch to Light mode" : "Switch to Dark mode"}
|
title={isDark ? 'Switch to Light mode' : 'Switch to Dark mode'}
|
||||||
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
|
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
|
||||||
on:click={toggleDark}
|
on:click={toggleDark}
|
||||||
>
|
>
|
||||||
@@ -350,7 +353,7 @@
|
|||||||
<div class="i-codicon-chrome-minimize" />
|
<div class="i-codicon-chrome-minimize" />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
title={isWindowMaximized ? "Restore" : "Maximize"}
|
title={isWindowMaximized ? 'Restore' : 'Maximize'}
|
||||||
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
|
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
|
||||||
on:click={toggleMaximize}
|
on:click={toggleMaximize}
|
||||||
>
|
>
|
||||||
@@ -393,7 +396,7 @@
|
|||||||
bg-darkPrimaryLighter transition-colors-250 overflow-hidden grid select-none px-2"
|
bg-darkPrimaryLighter transition-colors-250 overflow-hidden grid select-none px-2"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
on:click={() => open("https://tauri.app/")}
|
on:click={() => open('https://tauri.app/')}
|
||||||
class="self-center p-7 cursor-pointer"
|
class="self-center p-7 cursor-pointer"
|
||||||
src="tauri_logo.png"
|
src="tauri_logo.png"
|
||||||
alt="Tauri logo"
|
alt="Tauri logo"
|
||||||
@@ -449,8 +452,8 @@
|
|||||||
href="##"
|
href="##"
|
||||||
class="nv {selected === view ? 'nv_selected' : ''}"
|
class="nv {selected === view ? 'nv_selected' : ''}"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
select(view);
|
select(view)
|
||||||
isSideBarOpen = false;
|
isSideBarOpen = false
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="{view.icon} mr-2" />
|
<div class="{view.icon} mr-2" />
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script>
|
||||||
|
import {
|
||||||
|
checkPermissions,
|
||||||
|
requestPermissions,
|
||||||
|
getCurrentPosition
|
||||||
|
} from '@tauri-apps/plugin-geolocation'
|
||||||
|
|
||||||
|
export let onMessage
|
||||||
|
|
||||||
|
async function getPosition() {
|
||||||
|
let permissions = await checkPermissions()
|
||||||
|
if (
|
||||||
|
permissions.location === 'prompt' ||
|
||||||
|
permissions.location === 'prompt-with-rationale'
|
||||||
|
) {
|
||||||
|
permissions = await requestPermissions(['location'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissions.location === 'granted') {
|
||||||
|
getCurrentPosition().then(onMessage).catch(onMessage)
|
||||||
|
} else {
|
||||||
|
onMessage('permission denied')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="btn" id="cli-matches" on:click={getPosition}>
|
||||||
|
Get Position
|
||||||
|
</button>
|
||||||
@@ -87,16 +87,31 @@ fn main() {
|
|||||||
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
|
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import { getCurrentPosition, watchPosition } from '@tauri-apps/plugin-log'
|
import {
|
||||||
|
checkPermissions,
|
||||||
|
requestPermissions,
|
||||||
|
getCurrentPosition,
|
||||||
|
watchPosition
|
||||||
|
} from '@tauri-apps/plugin-log'
|
||||||
|
|
||||||
const pos = await getCurrentPosition()
|
let permissions = await checkPermissions()
|
||||||
|
if (
|
||||||
|
permissions.location === 'prompt' ||
|
||||||
|
permissions.location === 'prompt-with-rationale'
|
||||||
|
) {
|
||||||
|
permissions = await requestPermissions(['location'])
|
||||||
|
}
|
||||||
|
|
||||||
await watchPosition(
|
if (permissions.location === 'granted') {
|
||||||
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 },
|
const pos = await getCurrentPosition()
|
||||||
(pos) => {
|
|
||||||
console.log(pos)
|
await watchPosition(
|
||||||
}
|
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 },
|
||||||
)
|
(pos) => {
|
||||||
|
console.log(pos)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|||||||
@@ -60,18 +60,8 @@ private const val ALIAS_COARSE_LOCATION: String = "coarseLocation"
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
||||||
private lateinit var implementation: Geolocation// = Geolocation(activity.applicationContext)
|
private lateinit var implementation: Geolocation
|
||||||
private var watchers = hashMapOf<Long, Invoke>()
|
private var watchers = hashMapOf<Long, Pair<Invoke, WatchArgs>>()
|
||||||
|
|
||||||
// If multiple permissions get requested in quick succession not all callbacks will be fired,
|
|
||||||
// So we'll store all requests ourselves instead of using the callback argument.
|
|
||||||
private var positionRequests = mutableListOf<Invoke>()
|
|
||||||
private var watchRequests = mutableListOf<Invoke>()
|
|
||||||
// If getCurrentPosition or watchPosition are called before a prior call is done requesting permission,
|
|
||||||
// the callback will be called with denied for the prior call(s) so we keep track of them to make sure
|
|
||||||
// to only run the logic on the last request.
|
|
||||||
// TODO: Find a better solution after switching to explicit requestPermissions call - likely needs changes in Tauri
|
|
||||||
private var ongoingPermissionRequests = 0;
|
|
||||||
|
|
||||||
override fun load(webView: WebView) {
|
override fun load(webView: WebView) {
|
||||||
super.load(webView)
|
super.load(webView)
|
||||||
@@ -86,8 +76,9 @@ class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
for (watcher in watchers.values) {
|
// resume watchers
|
||||||
startWatch(watcher)
|
for ((watcher, args) in watchers.values) {
|
||||||
|
startWatch(watcher, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,83 +103,39 @@ class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
@Command
|
@Command
|
||||||
fun getCurrentPosition(invoke: Invoke) {
|
fun getCurrentPosition(invoke: Invoke) {
|
||||||
val args = invoke.parseArgs(PositionOptions::class.java)
|
val args = invoke.parseArgs(PositionOptions::class.java)
|
||||||
val alias = getAlias(args.enableHighAccuracy)
|
|
||||||
|
|
||||||
if (getPermissionState(alias) != PermissionState.GRANTED) {
|
val location = implementation.getLastLocation(args.maximumAge)
|
||||||
Logger.error("NOT GRANTED");
|
if (location != null) {
|
||||||
this.positionRequests.add(invoke)
|
invoke.resolve(convertLocation(location))
|
||||||
this.ongoingPermissionRequests += 1
|
|
||||||
requestPermissionForAlias(alias, invoke, "positionPermissionCallback")
|
|
||||||
} else {
|
} else {
|
||||||
Logger.error("GRANTED");
|
implementation.sendLocation(args.enableHighAccuracy,
|
||||||
getPosition(invoke, args)
|
{ loc -> invoke.resolve(convertLocation(loc)) },
|
||||||
|
{ error -> invoke.reject(error) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PermissionCallback
|
@PermissionCallback
|
||||||
private fun positionPermissionCallback(invoke: Invoke) {
|
private fun positionPermissionCallback(invoke: Invoke) {
|
||||||
Logger.error("positionPermissionCallback - ongoingRequests: " + this.ongoingPermissionRequests.toString())
|
val permissionsResultJSON = JSObject()
|
||||||
|
permissionsResultJSON.put("location", getPermissionState(ALIAS_LOCATION))
|
||||||
this.ongoingPermissionRequests -= 1
|
permissionsResultJSON.put("coarseLocation", getPermissionState(ALIAS_COARSE_LOCATION))
|
||||||
|
invoke.resolve(permissionsResultJSON)
|
||||||
if (this.ongoingPermissionRequests > 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val pRequests = this.positionRequests.toTypedArray()
|
|
||||||
val wRequests = this.watchRequests.toTypedArray()
|
|
||||||
this.positionRequests.clear()
|
|
||||||
this.watchRequests.clear()
|
|
||||||
|
|
||||||
// TODO: capacitor only checks for coarse here
|
|
||||||
val permissionGranted = getPermissionState(ALIAS_COARSE_LOCATION) == PermissionState.GRANTED;
|
|
||||||
Logger.error("positionPermissionCallback - permissionGranted: $permissionGranted");
|
|
||||||
|
|
||||||
for (inv in pRequests) {
|
|
||||||
if (permissionGranted) {
|
|
||||||
val args = inv.parseArgs(PositionOptions::class.java)
|
|
||||||
|
|
||||||
implementation.sendLocation(args.enableHighAccuracy,
|
|
||||||
{ location -> inv.resolve(convertLocation(location)) },
|
|
||||||
{ error -> inv.reject(error) })
|
|
||||||
} else {
|
|
||||||
inv.reject("Location permission was denied.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (inv in wRequests) {
|
|
||||||
if (permissionGranted) {
|
|
||||||
startWatch(invoke)
|
|
||||||
} else {
|
|
||||||
inv.reject("Location permission was denied.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
fun watchPosition(invoke: Invoke) {
|
fun watchPosition(invoke: Invoke) {
|
||||||
val args = invoke.parseArgs(WatchArgs::class.java)
|
val args = invoke.parseArgs(WatchArgs::class.java)
|
||||||
val alias = getAlias(args.options.enableHighAccuracy)
|
startWatch(invoke, args)
|
||||||
|
|
||||||
if (getPermissionState(alias) != PermissionState.GRANTED) {
|
|
||||||
this.watchRequests.add(invoke)
|
|
||||||
this.ongoingPermissionRequests += 1
|
|
||||||
requestPermissionForAlias(alias, invoke, "positionPermissionCallback")
|
|
||||||
} else {
|
|
||||||
startWatch(invoke)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startWatch(invoke: Invoke) {
|
private fun startWatch(invoke: Invoke, args: WatchArgs) {
|
||||||
val args = invoke.parseArgs(WatchArgs::class.java)
|
|
||||||
|
|
||||||
implementation.requestLocationUpdates(
|
implementation.requestLocationUpdates(
|
||||||
args.options.enableHighAccuracy,
|
args.options.enableHighAccuracy,
|
||||||
args.options.timeout,
|
args.options.timeout,
|
||||||
{ location -> args.channel.send(convertLocation(location)) },
|
{ location -> args.channel.send(convertLocation(location)) },
|
||||||
{ error -> args.channel.sendObject(error) })
|
{ error -> args.channel.sendObject(error) })
|
||||||
|
|
||||||
watchers[args.channel.id] = invoke
|
watchers[args.channel.id] = Pair(invoke, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
@@ -204,19 +151,6 @@ class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
invoke.resolve()
|
invoke.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPosition(invoke: Invoke, options: PositionOptions) {
|
|
||||||
val location = implementation.getLastLocation(options.maximumAge)
|
|
||||||
if (location != null) {
|
|
||||||
Logger.error("getPosition location non-null")
|
|
||||||
invoke.resolve(convertLocation(location))
|
|
||||||
} else {
|
|
||||||
Logger.error("getPosition location null")
|
|
||||||
implementation.sendLocation(options.enableHighAccuracy,
|
|
||||||
{ loc -> invoke.resolve(convertLocation(loc)) },
|
|
||||||
{ error -> invoke.reject(error) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertLocation(location: Location): JSObject {
|
private fun convertLocation(location: Location): JSObject {
|
||||||
val ret = JSObject()
|
val ret = JSObject()
|
||||||
val coords = JSObject()
|
val coords = JSObject()
|
||||||
@@ -235,14 +169,4 @@ class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlias(enableHighAccuracy: Boolean): String {
|
|
||||||
var alias = ALIAS_LOCATION;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
if (!enableHighAccuracy) {
|
|
||||||
alias = ALIAS_COARSE_LOCATION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return alias
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function r(t,r,e,s){if("a"===e&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof r?t!==r||!s:!r.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?s:"a"===e?s.call(t):s?s.value:r.get(t)}function e(t,r,e,s,o){if("function"==typeof r?t!==r||!o:!r.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return r.set(t,e),e}var s,o,i,a;"function"==typeof SuppressedError&&SuppressedError;class n{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),o.set(this,0),i.set(this,{}),this.id=function(t,r=!1){return window.__TAURI_INTERNALS__.transformCallback(t,r)}((({message:t,id:a})=>{if(a===r(this,o,"f")){e(this,o,a+1),r(this,s,"f").call(this,t);const n=Object.keys(r(this,i,"f"));if(n.length>0){let t=a+1;for(const e of n.sort()){if(parseInt(e)!==t)break;{const o=r(this,i,"f")[e];delete r(this,i,"f")[e],r(this,s,"f").call(this,o),t+=1}}e(this,o,t)}}else r(this,i,"f")[a.toString()]=t}))}set onmessage(t){e(this,s,t)}get onmessage(){return r(this,s,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}async function c(t,r={},e){return window.__TAURI_INTERNALS__.invoke(t,r,e)}s=new WeakMap,o=new WeakMap,i=new WeakMap,function(t){t.WINDOW_RESIZED="tauri://resize",t.WINDOW_MOVED="tauri://move",t.WINDOW_CLOSE_REQUESTED="tauri://close-requested",t.WINDOW_DESTROYED="tauri://destroyed",t.WINDOW_FOCUS="tauri://focus",t.WINDOW_BLUR="tauri://blur",t.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",t.WINDOW_THEME_CHANGED="tauri://theme-changed",t.WINDOW_CREATED="tauri://window-created",t.WEBVIEW_CREATED="tauri://webview-created",t.DRAG_ENTER="tauri://drag-enter",t.DRAG_OVER="tauri://drag-over",t.DRAG_DROP="tauri://drag-drop",t.DRAG_LEAVE="tauri://drag-leave"}(a||(a={}));const u={async getCurrentPosition(t){try{return{status:"ok",data:await c("plugin:geolocation|get_current_position",{options:t})}}catch(t){if(t instanceof Error)throw t;return{status:"error",error:t}}},async watchPosition(t,r){try{return{status:"ok",data:await c("plugin:geolocation|watch_position",{options:t,channel:r})}}catch(t){if(t instanceof Error)throw t;return{status:"error",error:t}}},async clearWatch(t){try{return{status:"ok",data:await c("plugin:geolocation|clear_watch",{channelId:t})}}catch(t){if(t instanceof Error)throw t;return{status:"error",error:t}}},async checkPermissions(){try{return{status:"ok",data:await c("plugin:geolocation|check_permissions")}}catch(t){if(t instanceof Error)throw t;return{status:"error",error:t}}},async requestPermissions(t){try{return{status:"ok",data:await c("plugin:geolocation|request_permissions",{permissions:t})}}catch(t){if(t instanceof Error)throw t;return{status:"error",error:t}}}};const{getCurrentPosition:_,clearWatch:h,checkPermissions:f,requestPermissions:w}=u;return t.checkPermissions=f,t.clearWatch=h,t.getCurrentPosition=_,t.requestPermissions=w,t.watchPosition=async function(t,r){const e=new n;return e.onmessage=r,await u.watchPosition(t,e),e.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}
|
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function e(t,e,n,i){if("a"===n&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?i:"a"===n?i.call(t):i?i.value:e.get(t)}function n(t,e,n,i,o){if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,n),n}var i,o,s;"function"==typeof SuppressedError&&SuppressedError;class r{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),o.set(this,0),s.set(this,{}),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:r})=>{if(r===e(this,o,"f")){n(this,o,r+1),e(this,i,"f").call(this,t);const a=Object.keys(e(this,s,"f"));if(a.length>0){let t=r+1;for(const n of a.sort()){if(parseInt(n)!==t)break;{const o=e(this,s,"f")[n];delete e(this,s,"f")[n],e(this,i,"f").call(this,o),t+=1}}n(this,o,t)}}else e(this,s,"f")[r.toString()]=t}))}set onmessage(t){n(this,i,t)}get onmessage(){return e(this,i,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}async function a(t,e={},n){return window.__TAURI_INTERNALS__.invoke(t,e,n)}return i=new WeakMap,o=new WeakMap,s=new WeakMap,t.checkPermissions=async function(){return await async function(t){return a(`plugin:${t}|check_permissions`)}("geolocation")},t.clearWatch=async function(t){await a("plugin:geolocation|clear_watch",{channelId:t})},t.getCurrentPosition=async function(t){return await a("plugin:geolocation|get_current_position",{options:t})},t.requestPermissions=async function(t){return await a("plugin:geolocation|request_permissions",{permissions:t})},t.watchPosition=async function(t,e){const n=new r;return n.onmessage=t=>{"string"==typeof t?e(null,t):e(t)},await a("plugin:geolocation|watch_position",{options:t,channel:n}),n.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const COMMANDS: &[&str] = &[
|
|||||||
"watch_position",
|
"watch_position",
|
||||||
"clear_watch",
|
"clear_watch",
|
||||||
"check_permissions",
|
"check_permissions",
|
||||||
"clear_permissions",
|
"request_permissions",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -1,248 +0,0 @@
|
|||||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
// @ts-nocheck
|
|
||||||
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
|
|
||||||
|
|
||||||
/** user-defined commands **/
|
|
||||||
|
|
||||||
export const commands = {
|
|
||||||
async getCurrentPosition(
|
|
||||||
options: PositionOptions | null
|
|
||||||
): Promise<Result<Position, Error>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
data: await TAURI_INVOKE('plugin:geolocation|get_current_position', {
|
|
||||||
options
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e
|
|
||||||
else return { status: 'error', error: e as any }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async watchPosition(
|
|
||||||
options: PositionOptions,
|
|
||||||
channel: any
|
|
||||||
): Promise<Result<null, Error>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
data: await TAURI_INVOKE('plugin:geolocation|watch_position', {
|
|
||||||
options,
|
|
||||||
channel
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e
|
|
||||||
else return { status: 'error', error: e as any }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async clearWatch(channelId: number): Promise<Result<null, Error>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
data: await TAURI_INVOKE('plugin:geolocation|clear_watch', {
|
|
||||||
channelId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e
|
|
||||||
else return { status: 'error', error: e as any }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async checkPermissions(): Promise<Result<PermissionStatus, Error>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
data: await TAURI_INVOKE('plugin:geolocation|check_permissions')
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e
|
|
||||||
else return { status: 'error', error: e as any }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async requestPermissions(
|
|
||||||
permissions: PermissionType[] | null
|
|
||||||
): Promise<Result<PermissionStatus, Error>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: 'ok',
|
|
||||||
data: await TAURI_INVOKE('plugin:geolocation|request_permissions', {
|
|
||||||
permissions
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e
|
|
||||||
else return { status: 'error', error: e as any }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** user-defined events **/
|
|
||||||
|
|
||||||
/* export const events = __makeEvents__<{
|
|
||||||
randomNumber: RandomNumber;
|
|
||||||
}>({
|
|
||||||
randomNumber: "plugin:geolocation:random-number",
|
|
||||||
}); */
|
|
||||||
|
|
||||||
/** user-defined statics **/
|
|
||||||
|
|
||||||
/** user-defined types **/
|
|
||||||
|
|
||||||
export type Coordinates = {
|
|
||||||
/**
|
|
||||||
* Latitude in decimal degrees.
|
|
||||||
*/
|
|
||||||
latitude: number
|
|
||||||
/**
|
|
||||||
* Longitude in decimal degrees.
|
|
||||||
*/
|
|
||||||
longitude: number
|
|
||||||
/**
|
|
||||||
* Accuracy level of the latitude and longitude coordinates in meters.
|
|
||||||
*/
|
|
||||||
accuracy: number
|
|
||||||
/**
|
|
||||||
* Accuracy level of the altitude coordinate in meters, if available.
|
|
||||||
* Available on all iOS versions and on Android 8 and above.
|
|
||||||
*/
|
|
||||||
altitudeAccuracy: number | null
|
|
||||||
/**
|
|
||||||
* The altitude the user is at, if available.
|
|
||||||
*/
|
|
||||||
altitude: number | null
|
|
||||||
speed: number | null
|
|
||||||
/**
|
|
||||||
* The heading the user is facing, if available.
|
|
||||||
*/
|
|
||||||
heading: number | null
|
|
||||||
}
|
|
||||||
export type Error = never
|
|
||||||
/**
|
|
||||||
* Permission state.
|
|
||||||
*/
|
|
||||||
export type PermissionState =
|
|
||||||
/**
|
|
||||||
* Permission access has been granted.
|
|
||||||
*/
|
|
||||||
| 'granted'
|
|
||||||
/**
|
|
||||||
* Permission access has been denied.
|
|
||||||
*/
|
|
||||||
| 'denied'
|
|
||||||
/**
|
|
||||||
* The end user should be prompted for permission.
|
|
||||||
*/
|
|
||||||
| 'prompt'
|
|
||||||
export type PermissionStatus = {
|
|
||||||
/**
|
|
||||||
* Permission state for the location alias.
|
|
||||||
*
|
|
||||||
* On Android it requests/checks both ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions.
|
|
||||||
*
|
|
||||||
* On iOS it requests/checks location permissions.
|
|
||||||
*/
|
|
||||||
location: PermissionState
|
|
||||||
/**
|
|
||||||
* Permissions state for the coarseLoaction alias.
|
|
||||||
*
|
|
||||||
* On Android it requests/checks ACCESS_COARSE_LOCATION.
|
|
||||||
*
|
|
||||||
* On Android 12+, users can choose between Approximate location (ACCESS_COARSE_LOCATION) and Precise location (ACCESS_FINE_LOCATION).
|
|
||||||
*
|
|
||||||
* On iOS it will have the same value as the `location` alias.
|
|
||||||
*/
|
|
||||||
coarseLocation: PermissionState
|
|
||||||
}
|
|
||||||
export type PermissionType = 'location' | 'coarseLocation'
|
|
||||||
export type Position = {
|
|
||||||
/**
|
|
||||||
* Creation time for these coordinates.
|
|
||||||
*/
|
|
||||||
timestamp: number
|
|
||||||
/**
|
|
||||||
* The GPD coordinates along with the accuracy of the data.
|
|
||||||
*/
|
|
||||||
coords: Coordinates
|
|
||||||
}
|
|
||||||
export type PositionOptions = {
|
|
||||||
/**
|
|
||||||
* High accuracy mode (such as GPS, if available)
|
|
||||||
* Will be ignored on Android 12+ if users didn't grant the ACCESS_FINE_LOCATION permission.
|
|
||||||
*/
|
|
||||||
enableHighAccuracy: boolean
|
|
||||||
/**
|
|
||||||
* The maximum wait time in milliseconds for location updates.
|
|
||||||
* On Android the timeout gets ignored for getCurrentPosition.
|
|
||||||
* Ignored on iOS
|
|
||||||
*/
|
|
||||||
timeout: number
|
|
||||||
/**
|
|
||||||
* The maximum age in milliseconds of a possible cached position that is acceptable to return.
|
|
||||||
* Default: 0
|
|
||||||
* Ignored on iOS
|
|
||||||
*/
|
|
||||||
maximumAge: number
|
|
||||||
}
|
|
||||||
//export type RandomNumber = number;
|
|
||||||
|
|
||||||
/** tauri-specta globals **/
|
|
||||||
|
|
||||||
import { invoke as TAURI_INVOKE } from '@tauri-apps/api/core'
|
|
||||||
import * as TAURI_API_EVENT from '@tauri-apps/api/event'
|
|
||||||
import { type WebviewWindow as __WebviewWindow__ } from '@tauri-apps/api/webviewWindow'
|
|
||||||
|
|
||||||
type __EventObj__<T> = {
|
|
||||||
listen: (
|
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>
|
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>
|
|
||||||
once: (
|
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>
|
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.once<T>>
|
|
||||||
emit: T extends null
|
|
||||||
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
|
||||||
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Result<T, E> =
|
|
||||||
| { status: 'ok'; data: T }
|
|
||||||
| { status: 'error'; error: E }
|
|
||||||
|
|
||||||
function __makeEvents__<T extends Record<string, any>>(
|
|
||||||
mappings: Record<keyof T, string>
|
|
||||||
) {
|
|
||||||
return new Proxy(
|
|
||||||
{} as unknown as {
|
|
||||||
[K in keyof T]: __EventObj__<T[K]> & {
|
|
||||||
(handle: __WebviewWindow__): __EventObj__<T[K]>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
get: (_, event) => {
|
|
||||||
const name = mappings[event as keyof T]
|
|
||||||
|
|
||||||
return new Proxy((() => {}) as any, {
|
|
||||||
apply: (_, __, [window]: [__WebviewWindow__]) => ({
|
|
||||||
listen: (arg: any) => window.listen(name, arg),
|
|
||||||
once: (arg: any) => window.once(name, arg),
|
|
||||||
emit: (arg: any) => window.emit(name, arg)
|
|
||||||
}),
|
|
||||||
get: (_, command: keyof __EventObj__<any>) => {
|
|
||||||
switch (command) {
|
|
||||||
case 'listen':
|
|
||||||
return (arg: any) => TAURI_API_EVENT.listen(name, arg)
|
|
||||||
case 'once':
|
|
||||||
return (arg: any) => TAURI_API_EVENT.once(name, arg)
|
|
||||||
case 'emit':
|
|
||||||
return (arg: any) => TAURI_API_EVENT.emit(name, arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -2,36 +2,137 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
import {
|
||||||
|
Channel,
|
||||||
|
invoke,
|
||||||
|
PermissionState,
|
||||||
|
checkPermissions as checkPluginPermissions
|
||||||
|
} from '@tauri-apps/api/core'
|
||||||
|
|
||||||
import { Channel } from '@tauri-apps/api/core'
|
export type Coordinates = {
|
||||||
import { commands, type PositionOptions, type Position } from './bindings'
|
/**
|
||||||
|
* Latitude in decimal degrees.
|
||||||
|
*/
|
||||||
|
latitude: number
|
||||||
|
/**
|
||||||
|
* Longitude in decimal degrees.
|
||||||
|
*/
|
||||||
|
longitude: number
|
||||||
|
/**
|
||||||
|
* Accuracy level of the latitude and longitude coordinates in meters.
|
||||||
|
*/
|
||||||
|
accuracy: number
|
||||||
|
/**
|
||||||
|
* Accuracy level of the altitude coordinate in meters, if available.
|
||||||
|
* Available on all iOS versions and on Android 8 and above.
|
||||||
|
*/
|
||||||
|
altitudeAccuracy: number | null
|
||||||
|
/**
|
||||||
|
* The altitude the user is at, if available.
|
||||||
|
*/
|
||||||
|
altitude: number | null
|
||||||
|
speed: number | null
|
||||||
|
/**
|
||||||
|
* The heading the user is facing, if available.
|
||||||
|
*/
|
||||||
|
heading: number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PermissionStatus = {
|
||||||
|
/**
|
||||||
|
* Permission state for the location alias.
|
||||||
|
*
|
||||||
|
* On Android it requests/checks both ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions.
|
||||||
|
*
|
||||||
|
* On iOS it requests/checks location permissions.
|
||||||
|
*/
|
||||||
|
location: PermissionState
|
||||||
|
/**
|
||||||
|
* Permissions state for the coarseLoaction alias.
|
||||||
|
*
|
||||||
|
* On Android it requests/checks ACCESS_COARSE_LOCATION.
|
||||||
|
*
|
||||||
|
* On Android 12+, users can choose between Approximate location (ACCESS_COARSE_LOCATION) and Precise location (ACCESS_FINE_LOCATION).
|
||||||
|
*
|
||||||
|
* On iOS it will have the same value as the `location` alias.
|
||||||
|
*/
|
||||||
|
coarseLocation: PermissionState
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PermissionType = 'location' | 'coarseLocation'
|
||||||
|
|
||||||
|
export type Position = {
|
||||||
|
/**
|
||||||
|
* Creation time for these coordinates.
|
||||||
|
*/
|
||||||
|
timestamp: number
|
||||||
|
/**
|
||||||
|
* The GPD coordinates along with the accuracy of the data.
|
||||||
|
*/
|
||||||
|
coords: Coordinates
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PositionOptions = {
|
||||||
|
/**
|
||||||
|
* High accuracy mode (such as GPS, if available)
|
||||||
|
* Will be ignored on Android 12+ if users didn't grant the ACCESS_FINE_LOCATION permission (`coarseLocation` permission).
|
||||||
|
*/
|
||||||
|
enableHighAccuracy: boolean
|
||||||
|
/**
|
||||||
|
* The maximum wait time in milliseconds for location updates.
|
||||||
|
* On Android the timeout gets ignored for getCurrentPosition.
|
||||||
|
* Ignored on iOS
|
||||||
|
*/
|
||||||
|
timeout: number
|
||||||
|
/**
|
||||||
|
* The maximum age in milliseconds of a possible cached position that is acceptable to return.
|
||||||
|
* Default: 0
|
||||||
|
* Ignored on iOS
|
||||||
|
*/
|
||||||
|
maximumAge: number
|
||||||
|
}
|
||||||
|
|
||||||
export async function watchPosition(
|
export async function watchPosition(
|
||||||
options: PositionOptions,
|
options: PositionOptions,
|
||||||
// TODO: This can receive errors too
|
cb: (location: Position | null, error?: string) => void
|
||||||
cb: (location: Position | string) => void
|
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
const channel = new Channel<Position>()
|
const channel = new Channel<Position | string>()
|
||||||
channel.onmessage = cb
|
channel.onmessage = (message) => {
|
||||||
await commands.watchPosition(options, channel)
|
if (typeof message === 'string') {
|
||||||
|
cb(null, message)
|
||||||
|
} else {
|
||||||
|
cb(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await invoke('plugin:geolocation|watch_position', {
|
||||||
|
options,
|
||||||
|
channel
|
||||||
|
})
|
||||||
return channel.id
|
return channel.id
|
||||||
}
|
}
|
||||||
|
|
||||||
export const {
|
export async function getCurrentPosition(
|
||||||
getCurrentPosition,
|
options?: PositionOptions
|
||||||
clearWatch,
|
): Promise<Position> {
|
||||||
checkPermissions,
|
return await invoke('plugin:geolocation|get_current_position', {
|
||||||
requestPermissions
|
options
|
||||||
} = commands
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export type {
|
export async function clearWatch(channelId: number): Promise<void> {
|
||||||
PermissionState,
|
await invoke('plugin:geolocation|clear_watch', {
|
||||||
PermissionStatus,
|
channelId
|
||||||
PermissionType,
|
})
|
||||||
Position,
|
}
|
||||||
PositionOptions,
|
|
||||||
Coordinates
|
|
||||||
} from './bindings'
|
|
||||||
|
|
||||||
// export { events };
|
export async function checkPermissions(): Promise<PermissionStatus> {
|
||||||
|
return await checkPluginPermissions('geolocation')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function requestPermissions(
|
||||||
|
permissions: PermissionType[] | null
|
||||||
|
): Promise<PermissionStatus> {
|
||||||
|
return await invoke('plugin:geolocation|request_permissions', {
|
||||||
|
permissions
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-clear-positions"
|
|
||||||
description = "Enables the clear_positions command without any pre-configured scope."
|
|
||||||
commands.allow = ["clear_positions"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-clear-positions"
|
|
||||||
description = "Denies the clear_positions command without any pre-configured scope."
|
|
||||||
commands.deny = ["clear_positions"]
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
[[permission]]
|
||||||
|
identifier = "allow-request-permissions"
|
||||||
|
description = "Enables the request_permissions command without any pre-configured scope."
|
||||||
|
commands.allow = ["request_permissions"]
|
||||||
|
|
||||||
|
[[permission]]
|
||||||
|
identifier = "deny-request-permissions"
|
||||||
|
description = "Denies the request_permissions command without any pre-configured scope."
|
||||||
|
commands.deny = ["request_permissions"]
|
||||||
@@ -63,32 +63,6 @@ Denies the clear_permissions command without any pre-configured scope.
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
`geolocation:allow-clear-positions`
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Enables the clear_positions command without any pre-configured scope.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
`geolocation:deny-clear-positions`
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Denies the clear_positions command without any pre-configured scope.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
`geolocation:allow-clear-watch`
|
`geolocation:allow-clear-watch`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@@ -141,6 +115,32 @@ Denies the get_current_position command without any pre-configured scope.
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
`geolocation:allow-request-permissions`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Enables the request_permissions command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`geolocation:deny-request-permissions`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Denies the request_permissions command without any pre-configured scope.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
`geolocation:allow-watch-position`
|
`geolocation:allow-watch-position`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -314,16 +314,6 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "deny-clear-permissions"
|
"const": "deny-clear-permissions"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "Enables the clear_positions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-clear-positions"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the clear_positions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-clear-positions"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Enables the clear_watch command without any pre-configured scope.",
|
"description": "Enables the clear_watch command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -344,6 +334,16 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "deny-get-current-position"
|
"const": "deny-get-current-position"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the request_permissions command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "allow-request-permissions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the request_permissions command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "deny-request-permissions"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Enables the watch_position command without any pre-configured scope.",
|
"description": "Enables the watch_position command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -98,7 +98,10 @@ impl<R: Runtime> Geolocation<R> {
|
|||||||
permissions: Option<Vec<PermissionType>>,
|
permissions: Option<Vec<PermissionType>>,
|
||||||
) -> crate::Result<PermissionStatus> {
|
) -> crate::Result<PermissionStatus> {
|
||||||
self.0
|
self.0
|
||||||
.run_mobile_plugin("requestPermissions", permissions)
|
.run_mobile_plugin(
|
||||||
|
"requestPermissions",
|
||||||
|
serde_json::json!({ "permissions": permissions }),
|
||||||
|
)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+6
@@ -78,9 +78,15 @@ importers:
|
|||||||
'@tauri-apps/plugin-fs':
|
'@tauri-apps/plugin-fs':
|
||||||
specifier: 2.0.0-rc.2
|
specifier: 2.0.0-rc.2
|
||||||
version: link:../../plugins/fs
|
version: link:../../plugins/fs
|
||||||
|
'@tauri-apps/plugin-geolocation':
|
||||||
|
specifier: 2.0.0-rc.1
|
||||||
|
version: link:../../plugins/geolocation
|
||||||
'@tauri-apps/plugin-global-shortcut':
|
'@tauri-apps/plugin-global-shortcut':
|
||||||
specifier: 2.0.0-rc.1
|
specifier: 2.0.0-rc.1
|
||||||
version: link:../../plugins/global-shortcut
|
version: link:../../plugins/global-shortcut
|
||||||
|
'@tauri-apps/plugin-haptics':
|
||||||
|
specifier: 2.0.0-rc.1
|
||||||
|
version: link:../../plugins/haptics
|
||||||
'@tauri-apps/plugin-http':
|
'@tauri-apps/plugin-http':
|
||||||
specifier: 2.0.0-rc.2
|
specifier: 2.0.0-rc.2
|
||||||
version: link:../../plugins/http
|
version: link:../../plugins/http
|
||||||
|
|||||||
Reference in New Issue
Block a user