replace device_query with tauri API so no need for accessibility perm
on darwin
This commit is contained in:
@@ -80,15 +80,9 @@ async getSceneConfiguration() : Promise<SceneConfiguration> {
|
||||
async updateSceneConfiguration(configuration: SceneConfiguration) : Promise<SceneConfiguration> {
|
||||
return await TAURI_INVOKE("update_scene_configuration", { configuration });
|
||||
},
|
||||
async getOnboardingStatus() : Promise<OnboardingStatus> {
|
||||
return await TAURI_INVOKE("get_onboarding_status");
|
||||
},
|
||||
async completeOnboarding() : Promise<null> {
|
||||
return await TAURI_INVOKE("complete_onboarding");
|
||||
},
|
||||
async requestAccessibilityPermission() : Promise<boolean> {
|
||||
return await TAURI_INVOKE("request_accessibility_permission");
|
||||
},
|
||||
async getAutostartEnabled() : Promise<boolean> {
|
||||
return await TAURI_INVOKE("get_autostart_enabled");
|
||||
},
|
||||
@@ -121,7 +115,6 @@ friendStatusesChanged: FriendStatusesChanged,
|
||||
friendsChanged: FriendsChanged,
|
||||
localeChanged: LocaleChanged,
|
||||
networkStatusChanged: NetworkStatusChanged,
|
||||
onboardingStatus: OnboardingStatus,
|
||||
profileChanged: ProfileChanged,
|
||||
puppetStatesChanged: PuppetStatesChanged,
|
||||
remotesChanged: RemotesChanged,
|
||||
@@ -135,7 +128,6 @@ friendStatusesChanged: "friend-statuses-changed",
|
||||
friendsChanged: "friends-changed",
|
||||
localeChanged: "locale-changed",
|
||||
networkStatusChanged: "network-status-changed",
|
||||
onboardingStatus: "onboarding-status",
|
||||
profileChanged: "profile-changed",
|
||||
puppetStatesChanged: "puppet-states-changed",
|
||||
remotesChanged: "remotes-changed",
|
||||
@@ -179,7 +171,6 @@ export type InteractionContent = { type: "text"; text: string } | { type: "wave"
|
||||
export type LiveDataSnapshot = { cursorPositions: Partial<{ [key in string]: CursorPositions }>; foregroundApps: Partial<{ [key in string]: AppMeta }> }
|
||||
export type LocaleChanged = { preference: string; locale: string }
|
||||
export type NetworkStatusChanged = { statuses: ConnectionStatus[] }
|
||||
export type OnboardingStatus = { onboardingDone: boolean; macosAccessibilityPermissionGranted: boolean; requiresAccessibilityPermission: boolean }
|
||||
export type ProfileChanged = { profile: User }
|
||||
export type PuppetMovementMode = "free" | "bottom"
|
||||
export type PuppetState = { id: string; position: CursorPosition; isMoving: boolean }
|
||||
|
||||
@@ -83,8 +83,6 @@ export function errorMessage(cause: unknown): string {
|
||||
return compiledMessages.error_profile_loading();
|
||||
case "Choose a 64×64 PNG skin before continuing.":
|
||||
return compiledMessages.error_skin_required();
|
||||
case "Turn on Friendolls in macOS Accessibility settings before continuing.":
|
||||
return compiledMessages.error_accessibility_required();
|
||||
case "Identification key is not valid base64url.":
|
||||
return compiledMessages.error_key_invalid_base64();
|
||||
case "Identification key must encode a 32-byte public key.":
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import {
|
||||
commands,
|
||||
events,
|
||||
type OnboardingStatus,
|
||||
type PuppetMovementMode,
|
||||
type RemoteInput,
|
||||
type SceneConfiguration,
|
||||
type User,
|
||||
} from "$lib/bindings";
|
||||
import PanelMessage from "$lib/components/control-panel/panel-message.svelte";
|
||||
import AccessibilityStep from "./components/accessibility-step.svelte";
|
||||
import CompleteStep from "./components/complete-step.svelte";
|
||||
import FriendStep from "./components/friend-step.svelte";
|
||||
import IdentityStep from "./components/identity-step.svelte";
|
||||
@@ -34,7 +31,6 @@
|
||||
| "movement"
|
||||
| "server"
|
||||
| "friend"
|
||||
| "accessibility"
|
||||
| "complete";
|
||||
|
||||
const allSteps: Array<{
|
||||
@@ -72,11 +68,6 @@
|
||||
title: (catalog) => catalog.onboarding_friend_title(),
|
||||
navigationLabel: (catalog) => catalog.onboarding_friend_nav(),
|
||||
},
|
||||
{
|
||||
id: "accessibility",
|
||||
title: (catalog) => catalog.onboarding_accessibility_title(),
|
||||
navigationLabel: (catalog) => catalog.onboarding_accessibility_nav(),
|
||||
},
|
||||
{
|
||||
id: "complete",
|
||||
title: (catalog) => catalog.onboarding_complete_title(),
|
||||
@@ -84,7 +75,6 @@
|
||||
},
|
||||
];
|
||||
|
||||
let status = $state<OnboardingStatus | null>(null);
|
||||
let profile = $state<User | null>(null);
|
||||
let configuration = $state<SceneConfiguration>({
|
||||
puppetScale: 1,
|
||||
@@ -92,7 +82,6 @@
|
||||
puppetMovementMode: "free",
|
||||
hideLocalPuppetWhenAlone: false,
|
||||
});
|
||||
let remediation = $state(false);
|
||||
let stepIndex = $state(0);
|
||||
let busy = $state(false);
|
||||
let error = $state("");
|
||||
@@ -118,19 +107,8 @@
|
||||
});
|
||||
});
|
||||
|
||||
let steps = $derived(
|
||||
remediation
|
||||
? allSteps.filter((candidate) => candidate.id === "accessibility")
|
||||
: allSteps.filter(
|
||||
(candidate) =>
|
||||
candidate.id !== "accessibility" ||
|
||||
status?.requiresAccessibilityPermission,
|
||||
),
|
||||
);
|
||||
let steps = $derived(allSteps);
|
||||
let step = $derived(steps[stepIndex] ?? steps[0]);
|
||||
let permissionGranted = $derived(
|
||||
status?.macosAccessibilityPermissionGranted ?? false,
|
||||
);
|
||||
let isLastStep = $derived(stepIndex === steps.length - 1);
|
||||
|
||||
$effect(() => {
|
||||
@@ -138,22 +116,16 @@
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
let unlisten: (() => void) | undefined;
|
||||
let disposed = false;
|
||||
|
||||
void (async () => {
|
||||
try {
|
||||
unlisten = await events.onboardingStatus.listen((event) => {
|
||||
status = event.payload;
|
||||
});
|
||||
const [nextStatus, nextProfile, nextConfiguration] = await Promise.all([
|
||||
commands.getOnboardingStatus(),
|
||||
const [nextProfile, nextConfiguration] = await Promise.all([
|
||||
commands.getProfile(),
|
||||
commands.getSceneConfiguration(),
|
||||
]);
|
||||
if (disposed) return;
|
||||
|
||||
status = nextStatus;
|
||||
profile = nextProfile;
|
||||
configuration = nextConfiguration;
|
||||
displayName = nextProfile.displayNameConfigured
|
||||
@@ -165,9 +137,7 @@
|
||||
const requestedStep = new URLSearchParams(window.location.search).get(
|
||||
"step",
|
||||
);
|
||||
remediation =
|
||||
requestedStep === "accessibility" && nextStatus.onboardingDone;
|
||||
if (!remediation && requestedStep) {
|
||||
if (requestedStep) {
|
||||
const requestedIndex = steps.findIndex(
|
||||
(candidate) => candidate.id === requestedStep,
|
||||
);
|
||||
@@ -180,7 +150,6 @@
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
unlisten?.();
|
||||
};
|
||||
});
|
||||
|
||||
@@ -256,8 +225,6 @@
|
||||
savedFriendId = (await commands.createFriend(nextFriendId)).id;
|
||||
if (previousFriendId) await commands.deleteFriend(previousFriendId);
|
||||
}
|
||||
} else if (step.id === "accessibility" && !permissionGranted) {
|
||||
throw new Error($messages.error_accessibility_required());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,9 +234,7 @@
|
||||
error = "";
|
||||
try {
|
||||
await saveCurrentStep();
|
||||
if (remediation) {
|
||||
await getCurrentWindow().close();
|
||||
} else if (isLastStep) {
|
||||
if (isLastStep) {
|
||||
await commands.completeOnboarding();
|
||||
await getCurrentWindow().close();
|
||||
} else {
|
||||
@@ -288,21 +253,6 @@
|
||||
error = "";
|
||||
}
|
||||
}
|
||||
|
||||
async function requestAccessibilityPermission() {
|
||||
busy = true;
|
||||
error = "";
|
||||
try {
|
||||
const granted = await commands.requestAccessibilityPermission();
|
||||
if (!granted) {
|
||||
error = $messages.accessibility_settings_opened();
|
||||
}
|
||||
} catch (cause) {
|
||||
error = errorMessage(cause);
|
||||
} finally {
|
||||
busy = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head><title>{$messages.onboarding_window_title()}</title></svelte:head>
|
||||
@@ -345,23 +295,17 @@
|
||||
<div class="min-h-0 flex-1 overflow-y-auto p-6">
|
||||
{#if error}
|
||||
<div class="mb-3">
|
||||
<PanelMessage
|
||||
kind={step.id === "accessibility" && !permissionGranted
|
||||
? "warning"
|
||||
: "error"}>{error}</PanelMessage
|
||||
>
|
||||
<PanelMessage kind="error">{error}</PanelMessage>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !status || !profile}
|
||||
{#if !profile}
|
||||
<div class="space-y-3" aria-label={$messages.onboarding_loading()}>
|
||||
<div class="skeleton h-5 w-2/3"></div>
|
||||
<div class="skeleton h-24 w-full"></div>
|
||||
</div>
|
||||
{:else if step.id === "welcome"}
|
||||
<WelcomeStep
|
||||
requiresAccessibilityPermission={status.requiresAccessibilityPermission}
|
||||
/>
|
||||
<WelcomeStep />
|
||||
{:else if step.id === "identity"}
|
||||
<IdentityStep bind:displayName {busy} />
|
||||
{:else if step.id === "skin"}
|
||||
@@ -385,12 +329,6 @@
|
||||
/>
|
||||
{:else if step.id === "friend"}
|
||||
<FriendStep bind:friendId {busy} />
|
||||
{:else if step.id === "accessibility"}
|
||||
<AccessibilityStep
|
||||
{permissionGranted}
|
||||
{busy}
|
||||
onrequest={requestAccessibilityPermission}
|
||||
/>
|
||||
{:else if step.id === "complete"}
|
||||
<CompleteStep />
|
||||
{/if}
|
||||
@@ -400,36 +338,29 @@
|
||||
class="flex shrink-0 items-center justify-between border-t border-base-300 bg-base-200 px-4 py-3"
|
||||
>
|
||||
<span class="text-[10px] text-base-content/60">
|
||||
{remediation
|
||||
? $messages.onboarding_permission_repair()
|
||||
: $messages.onboarding_step_count({
|
||||
current: stepIndex + 1,
|
||||
total: steps.length,
|
||||
})}
|
||||
{$messages.onboarding_step_count({
|
||||
current: stepIndex + 1,
|
||||
total: steps.length,
|
||||
})}
|
||||
</span>
|
||||
<div class="flex justify-end gap-2">
|
||||
{#if !remediation}
|
||||
<button
|
||||
class="btn min-w-20"
|
||||
type="button"
|
||||
disabled={busy || stepIndex === 0}
|
||||
onclick={back}>{$messages.onboarding_back()}</button
|
||||
>
|
||||
{/if}
|
||||
<button
|
||||
class="btn min-w-20"
|
||||
type="button"
|
||||
disabled={busy ||
|
||||
(step.id === "accessibility" && !permissionGranted)}
|
||||
disabled={busy || stepIndex === 0}
|
||||
onclick={back}>{$messages.onboarding_back()}</button
|
||||
>
|
||||
<button
|
||||
class="btn min-w-20"
|
||||
type="button"
|
||||
disabled={busy}
|
||||
onclick={next}
|
||||
>
|
||||
{busy
|
||||
? $messages.onboarding_working()
|
||||
: remediation
|
||||
? $messages.onboarding_done()
|
||||
: isLastStep
|
||||
? $messages.onboarding_finish()
|
||||
: $messages.onboarding_next()}
|
||||
: isLastStep
|
||||
? $messages.onboarding_finish()
|
||||
: $messages.onboarding_next()}
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<script lang="ts">
|
||||
import PanelMessage from "$lib/components/control-panel/panel-message.svelte";
|
||||
import { messages } from "$lib/i18n";
|
||||
|
||||
let {
|
||||
permissionGranted,
|
||||
busy,
|
||||
onrequest,
|
||||
}: { permissionGranted: boolean; busy: boolean; onrequest: () => void } =
|
||||
$props();
|
||||
</script>
|
||||
|
||||
<div class="space-y-4">
|
||||
<PanelMessage kind={permissionGranted ? "success" : "warning"}>
|
||||
{permissionGranted
|
||||
? $messages.accessibility_granted()
|
||||
: $messages.accessibility_waiting()}
|
||||
</PanelMessage>
|
||||
<fieldset class="fieldset border border-base-300 bg-base-100 p-4">
|
||||
<legend class="fieldset-legend px-1">{$messages.accessibility_why()}</legend>
|
||||
<p class="text-xs leading-relaxed">{$messages.accessibility_explanation()}</p>
|
||||
<ol class="mt-3 list-decimal space-y-1 pl-5 text-xs">
|
||||
<li>{$messages.accessibility_step_open()}</li>
|
||||
<li>{$messages.accessibility_step_enable()}</li>
|
||||
<li>{$messages.accessibility_step_return()}</li>
|
||||
</ol>
|
||||
<button
|
||||
class="btn mt-4 w-fit"
|
||||
type="button"
|
||||
disabled={busy || permissionGranted}
|
||||
onclick={onrequest}
|
||||
>
|
||||
{permissionGranted
|
||||
? $messages.accessibility_access_granted()
|
||||
: $messages.accessibility_open_settings()}
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
@@ -8,10 +8,6 @@
|
||||
} from "$lib/i18n";
|
||||
import PanelMessage from "$lib/components/control-panel/panel-message.svelte";
|
||||
|
||||
let {
|
||||
requiresAccessibilityPermission,
|
||||
}: { requiresAccessibilityPermission: boolean } = $props();
|
||||
|
||||
let busy = $state(false);
|
||||
let error = $state("");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user