add clipboard perms
This commit is contained in:
parent
27201416c7
commit
ad63d4c0e1
@ -24,7 +24,8 @@
|
|||||||
"optional_permissions": [
|
"optional_permissions": [
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
"https://*/*",
|
"https://*/*",
|
||||||
"webRequest"
|
"webRequest",
|
||||||
|
"clipboardRead"
|
||||||
],
|
],
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
"default_icon": {
|
"default_icon": {
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optional_permissions": [
|
"optional_permissions": [
|
||||||
"webRequest"
|
"webRequest",
|
||||||
|
"clipboardRead"
|
||||||
],
|
],
|
||||||
"host_permissions": [
|
"host_permissions": [
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
|
@ -42,14 +42,6 @@ if (isFirefox) {
|
|||||||
setupPlatform(chromeAPI);
|
setupPlatform(chromeAPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
platform.registerOnInstalled(() => {
|
|
||||||
platform.openWalletPage("/welcome");
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setGlobalLogLevelFromString("trace")
|
// setGlobalLogLevelFromString("trace")
|
||||||
platform.notifyWhenAppIsReady(() => {
|
platform.notifyWhenAppIsReady(() => {
|
||||||
wxMain();
|
wxMain();
|
||||||
|
@ -20,21 +20,21 @@ import { platform } from "../platform/api.js";
|
|||||||
import { ToggleHandler } from "../mui/handlers.js";
|
import { ToggleHandler } from "../mui/handlers.js";
|
||||||
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
export function useExtendedPermissions(): ToggleHandler {
|
export function useAutoOpenPermissions(): ToggleHandler {
|
||||||
const [enabled, setEnabled] = useState(false);
|
const [enabled, setEnabled] = useState(false);
|
||||||
const [error, setError] = useState<TalerError | undefined>();
|
const [error, setError] = useState<TalerError | undefined>();
|
||||||
const toggle = async (): Promise<void> => {
|
const toggle = async (): Promise<void> => {
|
||||||
return handleExtendedPerm(enabled, setEnabled).catch((e) => {
|
return handleAutoOpenPerm(enabled, setEnabled).catch((e) => {
|
||||||
setError(TalerError.fromException(e));
|
setError(TalerError.fromException(e));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getExtendedPermValue(): Promise<void> {
|
async function getValue(): Promise<void> {
|
||||||
const res = await wxApi.containsHeaderListener();
|
const res = await wxApi.containsHeaderListener();
|
||||||
setEnabled(res.newValue);
|
setEnabled(res.newValue);
|
||||||
}
|
}
|
||||||
getExtendedPermValue();
|
getValue();
|
||||||
}, []);
|
}, []);
|
||||||
return {
|
return {
|
||||||
value: enabled,
|
value: enabled,
|
||||||
@ -45,7 +45,7 @@ export function useExtendedPermissions(): ToggleHandler {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleExtendedPerm(
|
async function handleAutoOpenPerm(
|
||||||
isEnabled: boolean,
|
isEnabled: boolean,
|
||||||
onChange: (value: boolean) => void,
|
onChange: (value: boolean) => void,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2022 Taler Systems S.A.
|
||||||
|
|
||||||
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useState, useEffect } from "preact/hooks";
|
||||||
|
import * as wxApi from "../wxApi.js";
|
||||||
|
import { platform } from "../platform/api.js";
|
||||||
|
import { ToggleHandler } from "../mui/handlers.js";
|
||||||
|
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
|
export function useClipboardPermissions(): ToggleHandler {
|
||||||
|
const [enabled, setEnabled] = useState(false);
|
||||||
|
const [error, setError] = useState<TalerError | undefined>();
|
||||||
|
const toggle = async (): Promise<void> => {
|
||||||
|
return handleClipboardPerm(enabled, setEnabled).catch((e) => {
|
||||||
|
setError(TalerError.fromException(e));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getValue(): Promise<void> {
|
||||||
|
const res = await wxApi.containsHeaderListener();
|
||||||
|
setEnabled(res.newValue);
|
||||||
|
}
|
||||||
|
getValue();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: enabled,
|
||||||
|
button: {
|
||||||
|
onClick: toggle,
|
||||||
|
error,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleClipboardPerm(
|
||||||
|
isEnabled: boolean,
|
||||||
|
onChange: (value: boolean) => void,
|
||||||
|
): Promise<void> {
|
||||||
|
if (!isEnabled) {
|
||||||
|
// We set permissions here, since apparently FF wants this to be done
|
||||||
|
// as the result of an input event ...
|
||||||
|
let granted: boolean;
|
||||||
|
try {
|
||||||
|
granted = await platform.getPermissionsApi().requestClipboardPermissions();
|
||||||
|
} catch (lastError) {
|
||||||
|
onChange(false);
|
||||||
|
throw lastError;
|
||||||
|
}
|
||||||
|
// const res = await wxApi.toggleHeaderListener(granted);
|
||||||
|
onChange(granted);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await wxApi.toggleHeaderListener(false).then((r) => onChange(r.newValue));
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
@ -31,7 +31,6 @@ export function useTalerActionURL(): [
|
|||||||
);
|
);
|
||||||
const [dismissed, setDismissed] = useState(false);
|
const [dismissed, setDismissed] = useState(false);
|
||||||
const { findTalerUriInActiveTab, findTalerUriInClipboard } = useIocContext();
|
const { findTalerUriInActiveTab, findTalerUriInClipboard } = useIocContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function check(): Promise<void> {
|
async function check(): Promise<void> {
|
||||||
const clipUri = await findTalerUriInClipboard();
|
const clipUri = await findTalerUriInClipboard();
|
||||||
@ -52,7 +51,7 @@ export function useTalerActionURL(): [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
check();
|
check();
|
||||||
}, [setTalerActionUrl]);
|
}, []);
|
||||||
|
|
||||||
const url = dismissed ? undefined : talerActionUrl;
|
const url = dismissed ? undefined : talerActionUrl;
|
||||||
return [url, setDismissed];
|
return [url, setDismissed];
|
||||||
|
@ -37,6 +37,10 @@ export interface CrossBrowserPermissionsApi {
|
|||||||
requestHostPermissions(): Promise<boolean>;
|
requestHostPermissions(): Promise<boolean>;
|
||||||
removeHostPermissions(): Promise<boolean>;
|
removeHostPermissions(): Promise<boolean>;
|
||||||
|
|
||||||
|
containsClipboardPermissions(): Promise<boolean>;
|
||||||
|
requestClipboardPermissions(): Promise<boolean>;
|
||||||
|
removeClipboardPermissions(): Promise<boolean>;
|
||||||
|
|
||||||
addPermissionsListener(
|
addPermissionsListener(
|
||||||
callback: (p: Permissions, lastError?: string) => void,
|
callback: (p: Permissions, lastError?: string) => void,
|
||||||
): void;
|
): void;
|
||||||
|
@ -77,6 +77,18 @@ const hostPermissions = {
|
|||||||
origins: ["http://*/*", "https://*/*"],
|
origins: ["http://*/*", "https://*/*"],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function containsClipboardPermissions(): Promise<boolean> {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
chrome.permissions.contains({ permissions: ["clipboardRead"] }, (resp) => {
|
||||||
|
const le = chrome.runtime.lastError?.message;
|
||||||
|
if (le) {
|
||||||
|
rej(le);
|
||||||
|
}
|
||||||
|
res(resp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function containsHostPermissions(): Promise<boolean> {
|
export function containsHostPermissions(): Promise<boolean> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
chrome.permissions.contains(hostPermissions, (resp) => {
|
chrome.permissions.contains(hostPermissions, (resp) => {
|
||||||
@ -89,6 +101,18 @@ export function containsHostPermissions(): Promise<boolean> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function requestClipboardPermissions(): Promise<boolean> {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
chrome.permissions.request({ permissions: ["clipboardRead"] }, (resp) => {
|
||||||
|
const le = chrome.runtime.lastError?.message;
|
||||||
|
if (le) {
|
||||||
|
rej(le);
|
||||||
|
}
|
||||||
|
res(resp);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function requestHostPermissions(): Promise<boolean> {
|
export async function requestHostPermissions(): Promise<boolean> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
chrome.permissions.request(hostPermissions, (resp) => {
|
chrome.permissions.request(hostPermissions, (resp) => {
|
||||||
@ -155,6 +179,18 @@ export async function removeHostPermissions(): Promise<boolean> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeClipboardPermissions(): Promise<boolean> {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
chrome.permissions.remove({ permissions: ["clipboardRead"] }, (resp) => {
|
||||||
|
const le = chrome.runtime.lastError?.message;
|
||||||
|
if (le) {
|
||||||
|
rej(le);
|
||||||
|
}
|
||||||
|
res(resp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function addPermissionsListener(
|
function addPermissionsListener(
|
||||||
callback: (p: Permissions, lastError?: string) => void,
|
callback: (p: Permissions, lastError?: string) => void,
|
||||||
): void {
|
): void {
|
||||||
@ -170,6 +206,9 @@ function getPermissionsApi(): CrossBrowserPermissionsApi {
|
|||||||
containsHostPermissions,
|
containsHostPermissions,
|
||||||
requestHostPermissions,
|
requestHostPermissions,
|
||||||
removeHostPermissions,
|
removeHostPermissions,
|
||||||
|
requestClipboardPermissions,
|
||||||
|
removeClipboardPermissions,
|
||||||
|
containsClipboardPermissions,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,11 +421,9 @@ function registerTalerHeaderListener(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function tabListener(tabId: number, info: chrome.tabs.TabChangeInfo): Promise<void> {
|
async function tabListener(tabId: number, info: chrome.tabs.TabChangeInfo): Promise<void> {
|
||||||
console.log("tab update", tabId, info)
|
|
||||||
if (tabId < 0) return;
|
if (tabId < 0) return;
|
||||||
if (info.status !== "complete") return;
|
if (info.status !== "complete") return;
|
||||||
const uri = await findTalerUriInTab(tabId);
|
const uri = await findTalerUriInTab(tabId);
|
||||||
console.log("uri", uri)
|
|
||||||
if (!uri) return;
|
if (!uri) return;
|
||||||
logger.info(`Found a Taler URI in the tab ${tabId}`)
|
logger.info(`Found a Taler URI in the tab ${tabId}`)
|
||||||
callback(tabId, uri)
|
callback(tabId, uri)
|
||||||
@ -585,7 +622,6 @@ async function registerIconChangeOnTalerContent(): Promise<void> {
|
|||||||
chrome.tabs.onUpdated.addListener(
|
chrome.tabs.onUpdated.addListener(
|
||||||
async (tabId, info: chrome.tabs.TabChangeInfo) => {
|
async (tabId, info: chrome.tabs.TabChangeInfo) => {
|
||||||
if (tabId < 0) return;
|
if (tabId < 0) return;
|
||||||
logger.info("tab updated", tabId, info);
|
|
||||||
if (info.status !== "complete") return;
|
if (info.status !== "complete") return;
|
||||||
const uri = await findTalerUriInTab(tabId);
|
const uri = await findTalerUriInTab(tabId);
|
||||||
if (uri) {
|
if (uri) {
|
||||||
@ -690,9 +726,22 @@ async function findTalerUriInTab(tabId: number): Promise<string | undefined> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function timeout(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
async function findTalerUriInClipboard(): Promise<string | undefined> {
|
async function findTalerUriInClipboard(): Promise<string | undefined> {
|
||||||
const textInClipboard = await window.navigator.clipboard.readText();
|
try {
|
||||||
|
//It looks like clipboard promise does not return, so we need a timeout
|
||||||
|
const textInClipboard = await Promise.any([
|
||||||
|
timeout(100),
|
||||||
|
window.navigator.clipboard.readText()
|
||||||
|
])
|
||||||
|
if (!textInClipboard) return;
|
||||||
return textInClipboard.startsWith("taler://") || textInClipboard.startsWith("taler+http://") ? textInClipboard : undefined
|
return textInClipboard.startsWith("taler://") || textInClipboard.startsWith("taler+http://") ? textInClipboard : undefined
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("could not read clipboard", e)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findTalerUriInActiveTab(): Promise<string | undefined> {
|
async function findTalerUriInActiveTab(): Promise<string | undefined> {
|
||||||
|
@ -32,6 +32,9 @@ const api: PlatformAPI = {
|
|||||||
containsHostPermissions: async () => true,
|
containsHostPermissions: async () => true,
|
||||||
removeHostPermissions: async () => false,
|
removeHostPermissions: async () => false,
|
||||||
requestHostPermissions: async () => false,
|
requestHostPermissions: async () => false,
|
||||||
|
containsClipboardPermissions: async () => true,
|
||||||
|
removeClipboardPermissions: async () => false,
|
||||||
|
requestClipboardPermissions: async () => false,
|
||||||
}),
|
}),
|
||||||
getWalletWebExVersion: () => ({
|
getWalletWebExVersion: () => ({
|
||||||
version: "none",
|
version: "none",
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
import { CrossBrowserPermissionsApi, Permissions, PlatformAPI } from "./api.js";
|
import { CrossBrowserPermissionsApi, Permissions, PlatformAPI } from "./api.js";
|
||||||
import chromePlatform, {
|
import chromePlatform, {
|
||||||
containsHostPermissions as chromeContains,
|
containsHostPermissions as chromeHostContains,
|
||||||
removeHostPermissions as chromeRemove,
|
removeHostPermissions as chromeHostRemove,
|
||||||
requestHostPermissions as chromeRequest,
|
requestHostPermissions as chromeHostRequest,
|
||||||
|
containsClipboardPermissions as chromeClipContains,
|
||||||
|
removeClipboardPermissions as chromeClipRemove,
|
||||||
|
requestClipboardPermissions as chromeClipRequest,
|
||||||
} from "./chrome.js";
|
} from "./chrome.js";
|
||||||
|
|
||||||
const api: PlatformAPI = {
|
const api: PlatformAPI = {
|
||||||
@ -43,9 +46,12 @@ function addPermissionsListener(callback: (p: Permissions) => void): void {
|
|||||||
function getPermissionsApi(): CrossBrowserPermissionsApi {
|
function getPermissionsApi(): CrossBrowserPermissionsApi {
|
||||||
return {
|
return {
|
||||||
addPermissionsListener,
|
addPermissionsListener,
|
||||||
containsHostPermissions: chromeContains,
|
containsHostPermissions: chromeHostContains,
|
||||||
requestHostPermissions: chromeRequest,
|
requestHostPermissions: chromeHostRequest,
|
||||||
removeHostPermissions: chromeRemove,
|
removeHostPermissions: chromeHostRemove,
|
||||||
|
containsClipboardPermissions: chromeClipContains,
|
||||||
|
removeClipboardPermissions: chromeClipRemove,
|
||||||
|
requestClipboardPermissions: chromeClipRequest,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,21 +46,24 @@ const version = {
|
|||||||
|
|
||||||
export const AllOff = createExample(TestedComponent, {
|
export const AllOff = createExample(TestedComponent, {
|
||||||
deviceName: "this-is-the-device-name",
|
deviceName: "this-is-the-device-name",
|
||||||
permissionToggle: { value: false, button: {} },
|
autoOpenToggle: { value: false, button: {} },
|
||||||
|
clipboardToggle: { value: false, button: {} },
|
||||||
setDeviceName: () => Promise.resolve(),
|
setDeviceName: () => Promise.resolve(),
|
||||||
...version,
|
...version,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const OneChecked = createExample(TestedComponent, {
|
export const OneChecked = createExample(TestedComponent, {
|
||||||
deviceName: "this-is-the-device-name",
|
deviceName: "this-is-the-device-name",
|
||||||
permissionToggle: { value: false, button: {} },
|
autoOpenToggle: { value: false, button: {} },
|
||||||
|
clipboardToggle: { value: false, button: {} },
|
||||||
setDeviceName: () => Promise.resolve(),
|
setDeviceName: () => Promise.resolve(),
|
||||||
...version,
|
...version,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const WithOneExchange = createExample(TestedComponent, {
|
export const WithOneExchange = createExample(TestedComponent, {
|
||||||
deviceName: "this-is-the-device-name",
|
deviceName: "this-is-the-device-name",
|
||||||
permissionToggle: { value: false, button: {} },
|
autoOpenToggle: { value: false, button: {} },
|
||||||
|
clipboardToggle: { value: false, button: {} },
|
||||||
setDeviceName: () => Promise.resolve(),
|
setDeviceName: () => Promise.resolve(),
|
||||||
knownExchanges: [
|
knownExchanges: [
|
||||||
{
|
{
|
||||||
@ -80,7 +83,8 @@ export const WithOneExchange = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const WithExchangeInDifferentState = createExample(TestedComponent, {
|
export const WithExchangeInDifferentState = createExample(TestedComponent, {
|
||||||
deviceName: "this-is-the-device-name",
|
deviceName: "this-is-the-device-name",
|
||||||
permissionToggle: { value: false, button: {} },
|
autoOpenToggle: { value: false, button: {} },
|
||||||
|
clipboardToggle: { value: false, button: {} },
|
||||||
setDeviceName: () => Promise.resolve(),
|
setDeviceName: () => Promise.resolve(),
|
||||||
knownExchanges: [
|
knownExchanges: [
|
||||||
{
|
{
|
||||||
|
@ -33,17 +33,19 @@ import { useDevContext } from "../context/devContext.js";
|
|||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js";
|
import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js";
|
import { useAutoOpenPermissions } from "../hooks/useAutoOpenPermissions.js";
|
||||||
import { ToggleHandler } from "../mui/handlers.js";
|
import { ToggleHandler } from "../mui/handlers.js";
|
||||||
import { Pages } from "../NavigationBar.js";
|
import { Pages } from "../NavigationBar.js";
|
||||||
import { buildTermsOfServiceStatus } from "../utils/index.js";
|
import { buildTermsOfServiceStatus } from "../utils/index.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
import { platform } from "../platform/api.js";
|
import { platform } from "../platform/api.js";
|
||||||
|
import { useClipboardPermissions } from "../hooks/useClipboardPermissions.js";
|
||||||
|
|
||||||
const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
|
const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
|
||||||
|
|
||||||
export function SettingsPage(): VNode {
|
export function SettingsPage(): VNode {
|
||||||
const permissionToggle = useExtendedPermissions();
|
const autoOpenToggle = useAutoOpenPermissions();
|
||||||
|
const clipboardToggle = useClipboardPermissions();
|
||||||
const { devMode, toggleDevMode } = useDevContext();
|
const { devMode, toggleDevMode } = useDevContext();
|
||||||
const { name, update } = useBackupDeviceName();
|
const { name, update } = useBackupDeviceName();
|
||||||
const webex = platform.getWalletWebExVersion();
|
const webex = platform.getWalletWebExVersion();
|
||||||
@ -63,7 +65,8 @@ export function SettingsPage(): VNode {
|
|||||||
knownExchanges={exchanges}
|
knownExchanges={exchanges}
|
||||||
deviceName={name}
|
deviceName={name}
|
||||||
setDeviceName={update}
|
setDeviceName={update}
|
||||||
permissionToggle={permissionToggle}
|
autoOpenToggle={autoOpenToggle}
|
||||||
|
clipboardToggle={clipboardToggle}
|
||||||
developerMode={devMode}
|
developerMode={devMode}
|
||||||
toggleDeveloperMode={toggleDevMode}
|
toggleDeveloperMode={toggleDevMode}
|
||||||
webexVersion={{
|
webexVersion={{
|
||||||
@ -78,7 +81,8 @@ export function SettingsPage(): VNode {
|
|||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
deviceName: string;
|
deviceName: string;
|
||||||
setDeviceName: (s: string) => Promise<void>;
|
setDeviceName: (s: string) => Promise<void>;
|
||||||
permissionToggle: ToggleHandler;
|
autoOpenToggle: ToggleHandler;
|
||||||
|
clipboardToggle: ToggleHandler;
|
||||||
developerMode: boolean;
|
developerMode: boolean;
|
||||||
toggleDeveloperMode: () => Promise<void>;
|
toggleDeveloperMode: () => Promise<void>;
|
||||||
knownExchanges: Array<ExchangeListItem>;
|
knownExchanges: Array<ExchangeListItem>;
|
||||||
@ -91,7 +95,8 @@ export interface ViewProps {
|
|||||||
|
|
||||||
export function SettingsView({
|
export function SettingsView({
|
||||||
knownExchanges,
|
knownExchanges,
|
||||||
permissionToggle,
|
autoOpenToggle,
|
||||||
|
clipboardToggle,
|
||||||
developerMode,
|
developerMode,
|
||||||
coreVersion,
|
coreVersion,
|
||||||
webexVersion,
|
webexVersion,
|
||||||
@ -102,10 +107,16 @@ export function SettingsView({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<section>
|
<section>
|
||||||
{permissionToggle.button.error && (
|
{autoOpenToggle.button.error && (
|
||||||
<ErrorTalerOperation
|
<ErrorTalerOperation
|
||||||
title={<i18n.Translate>Could not toggle auto-open</i18n.Translate>}
|
title={<i18n.Translate>Could not toggle auto-open</i18n.Translate>}
|
||||||
error={permissionToggle.button.error.errorDetail}
|
error={autoOpenToggle.button.error.errorDetail}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{clipboardToggle.button.error && (
|
||||||
|
<ErrorTalerOperation
|
||||||
|
title={<i18n.Translate>Could not toggle clipboard</i18n.Translate>}
|
||||||
|
error={clipboardToggle.button.error.errorDetail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<SubTitle>
|
<SubTitle>
|
||||||
@ -117,15 +128,31 @@ export function SettingsView({
|
|||||||
Automatically open wallet based on page content
|
Automatically open wallet based on page content
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
}
|
}
|
||||||
name="perm"
|
name="autoOpen"
|
||||||
description={
|
description={
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Enabling this option below will make using the wallet faster, but
|
Enabling this option below will make using the wallet faster, but
|
||||||
requires more permissions from your browser.
|
requires more permissions from your browser.
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
}
|
}
|
||||||
enabled={permissionToggle.value!}
|
enabled={autoOpenToggle.value!}
|
||||||
onToggle={permissionToggle.button.onClick!}
|
onToggle={autoOpenToggle.button.onClick!}
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={
|
||||||
|
<i18n.Translate>
|
||||||
|
Automatically check clipboard for Taler URI
|
||||||
|
</i18n.Translate>
|
||||||
|
}
|
||||||
|
name="clipboard"
|
||||||
|
description={
|
||||||
|
<i18n.Translate>
|
||||||
|
Enabling this option below will make using the wallet faster, but
|
||||||
|
requires more permissions from your browser.
|
||||||
|
</i18n.Translate>
|
||||||
|
}
|
||||||
|
enabled={clipboardToggle.value!}
|
||||||
|
onToggle={clipboardToggle.button.onClick!}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SubTitle>
|
<SubTitle>
|
||||||
|
@ -26,12 +26,12 @@ import { Checkbox } from "../components/Checkbox.js";
|
|||||||
import { SubTitle, Title } from "../components/styled/index.js";
|
import { SubTitle, Title } from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useDiagnostics } from "../hooks/useDiagnostics.js";
|
import { useDiagnostics } from "../hooks/useDiagnostics.js";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js";
|
import { useAutoOpenPermissions } from "../hooks/useAutoOpenPermissions.js";
|
||||||
import { ToggleHandler } from "../mui/handlers.js";
|
import { ToggleHandler } from "../mui/handlers.js";
|
||||||
import { platform } from "../platform/api.js";
|
import { platform } from "../platform/api.js";
|
||||||
|
|
||||||
export function WelcomePage(): VNode {
|
export function WelcomePage(): VNode {
|
||||||
const permissionToggle = useExtendedPermissions();
|
const permissionToggle = useAutoOpenPermissions();
|
||||||
const [diagnostics, timedOut] = useDiagnostics();
|
const [diagnostics, timedOut] = useDiagnostics();
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
|
@ -329,11 +329,21 @@ export async function wxMain(): Promise<void> {
|
|||||||
|
|
||||||
platform.registerAllIncomingConnections();
|
platform.registerAllIncomingConnections();
|
||||||
|
|
||||||
|
try {
|
||||||
|
platform.registerOnInstalled(() => {
|
||||||
|
platform.openWalletPage("/welcome");
|
||||||
|
|
||||||
|
//
|
||||||
try {
|
try {
|
||||||
platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
|
platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("could not register header listener", e);
|
logger.error("could not register header listener", e);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// On platforms that support it, also listen to external
|
// On platforms that support it, also listen to external
|
||||||
// modification of permissions.
|
// modification of permissions.
|
||||||
|
Loading…
Reference in New Issue
Block a user