Skip to content

Commit

Permalink
release-app make permission simpler, more reactive
Browse files Browse the repository at this point in the history
  • Loading branch information
louis030195 committed Feb 24, 2025
1 parent 4e841b1 commit de935b3
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 172 deletions.
19 changes: 16 additions & 3 deletions screenpipe-app-tauri/components/pipe-store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ import {
} from "@/components/ui/tooltip";
import localforage from "localforage";
import { useLoginDialog } from "./login-dialog";
import { PermissionButtons } from "./status/permission-buttons";
import { usePlatform } from "@/lib/hooks/use-platform";

const corePipes: string[] = ["data-table", "search"];

export const PipeStore: React.FC = () => {
const { health } = useHealthCheck();
const [selectedPipe, setSelectedPipe] = useState<PipeWithStatus | null>(null);
const { settings, loadUser } = useSettings();
const { settings } = useSettings();
const [pipes, setPipes] = useState<PipeWithStatus[]>([]);
const [installedPipes, setInstalledPipes] = useState<InstalledPipe[]>([]);
const [searchQuery, setSearchQuery] = useState("");
Expand All @@ -52,7 +54,7 @@ export const PipeStore: React.FC = () => {
const [loadingInstalls, setLoadingInstalls] = useState<Set<string>>(
new Set()
);

const { isMac: isMacOS } = usePlatform();
const filteredPipes = pipes
.filter(
(pipe) =>
Expand Down Expand Up @@ -997,7 +999,7 @@ export const PipeStore: React.FC = () => {
if (health?.status === "error") {
return (
<div className="flex flex-col items-center justify-center h-screen p-4 space-y-4">
<div className="text-center space-y-4">
<div className="text-center space-y-4 max-w-md mx-auto justify-center items-center">
<h3 className="text-lg font-medium">screenpipe is not recording</h3>
<p className="text-sm text-muted-foreground">
please start the screenpipe service to browse and manage pipes
Expand All @@ -1010,6 +1012,17 @@ export const PipeStore: React.FC = () => {
<Power className="h-4 w-4" />
check service status
</Button>

{isMacOS && (
<div className="mt-6 pt-4 border-t w-full flex flex-col items-center">
<h4 className="text-sm font-medium mb-3">check permissions</h4>
<div className="space-y-2">
<PermissionButtons settings={settings} type="screen" />
<PermissionButtons settings={settings} type="audio" />
<PermissionButtons settings={settings} type="accessibility" />
</div>
</div>
)}
</div>
</div>
);
Expand Down
179 changes: 15 additions & 164 deletions screenpipe-app-tauri/components/screenpipe-status.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,32 @@
"use client";
import React, { useState, useEffect } from "react";
import React, { useState } from "react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Badge } from "./ui/badge";
import { invoke } from "@tauri-apps/api/core";
import { toast } from "./ui/use-toast";

import { Button } from "./ui/button";
import { Separator } from "./ui/separator";
import { useHealthCheck } from "@/lib/hooks/use-health-check";
import { Lock, Folder, Activity, Power } from "lucide-react";
import { Lock, Folder, Power, Settings } from "lucide-react";
import { open as openUrl } from "@tauri-apps/plugin-shell";

import { LogFileButton } from "./log-file-button";
import { DevModeSettings } from "./dev-mode-settings";
import { cn } from "@/lib/utils";
import { Check, X } from "lucide-react";
import { useSettings } from "@/lib/hooks/use-settings";
import { useStatusDialog } from "@/lib/hooks/use-status-dialog";
import { platform } from "@tauri-apps/plugin-os";

type PermissionsStatus = {
screenRecording: string;
microphone: string;
accessibility: string;
};
import { PermissionButtons } from "./status/permission-buttons";

const HealthStatus = ({ className }: { className?: string }) => {
const { health } = useHealthCheck();
const { isOpen, open, close } = useStatusDialog();
const { settings, getDataDir } = useSettings();
const [localDataDir, setLocalDataDir] = useState("");
const [permissions, setPermissions] = useState<PermissionsStatus | null>(
null
);
const [isMacOS, setIsMacOS] = useState(false);

useEffect(() => {
const checkPermissions = async () => {
try {
const perms = await invoke<PermissionsStatus>("do_permissions_check", {
initialCheck: true,
});

setPermissions({
screenRecording: perms.screenRecording,
microphone: perms.microphone,
accessibility: perms.accessibility,
});
} catch (error) {
console.error("Failed to check permissions:", error);
}
};
checkPermissions();
}, []);

useEffect(() => {
const checkPlatform = () => {
const currentPlatform = platform();
setIsMacOS(currentPlatform === "macos");
};
checkPlatform();
}, []);

const handleOpenDataDir = async () => {
try {
Expand Down Expand Up @@ -159,64 +120,6 @@ const HealthStatus = ({ className }: { className?: string }) => {
}
};

const handlePermissionButton = async (
type: "screen" | "audio" | "accessibility"
) => {
const toastId = toast({
title: `checking ${type} permissions`,
description: "please wait...",
duration: Infinity,
});

try {
const permissionType =
type === "screen"
? "screenRecording"
: type === "audio"
? "microphone"
: "accessibility";

await invoke("request_permission", {
permission: permissionType,
});

const perms = await invoke<PermissionsStatus>("do_permissions_check", {
initialCheck: false,
});

setPermissions({
screenRecording: perms.screenRecording,
microphone: perms.microphone,
accessibility: perms.accessibility,
});

const granted =
type === "screen"
? perms.screenRecording === "Granted"
: type === "audio"
? perms.microphone === "Granted"
: perms.accessibility === "Granted";

toastId.update({
id: toastId.id,
title: granted ? "permission granted" : "permission check complete",
description: granted
? `${type} permission was successfully granted`
: `please try granting ${type} permission again if needed`,
duration: 3000,
});
} catch (error) {
console.error(`failed to handle ${type} permission:`, error);
toastId.update({
id: toastId.id,
title: "error",
description: `failed to handle ${type} permission`,
variant: "destructive",
duration: 3000,
});
}
};

return (
<>
<Badge
Expand Down Expand Up @@ -274,27 +177,9 @@ const HealthStatus = ({ className }: { className?: string }) => {
{formatTimestamp(health?.last_frame_timestamp ?? null)}
</span>
</div>
{isMacOS && (
<div className="flex items-center gap-2">
{permissions && (
<span>
{permissions.screenRecording ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<X className="h-4 w-4 text-red-500" />
)}
</span>
)}
<Button
variant="outline"
className="w-[260px] text-sm justify-start"
onClick={() => handlePermissionButton("screen")}
>
<Lock className="h-4 w-4 mr-2" />
grant screen permission
</Button>
</div>
)}
<div className="flex-shrink-0">
<PermissionButtons type="screen" settings={settings} />
</div>
</div>

{/* Audio Recording Status */}
Expand Down Expand Up @@ -323,28 +208,9 @@ const HealthStatus = ({ className }: { className?: string }) => {
: formatTimestamp(health?.last_audio_timestamp ?? null)}
</span>
</div>
{isMacOS && (
<div className="flex items-center gap-2">
{permissions && (
<span>
{permissions.microphone ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<X className="h-4 w-4 text-red-500" />
)}
</span>
)}
<Button
variant="outline"
className="w-[260px] text-sm justify-start"
onClick={() => handlePermissionButton("audio")}
disabled={settings.disableAudio}
>
<Lock className="h-4 w-4 mr-2" />
grant audio permission
</Button>
</div>
)}
<div className="flex-shrink-0">
<PermissionButtons type="audio" settings={settings} />
</div>
</div>

{/* UI Monitoring Status */}
Expand All @@ -366,27 +232,12 @@ const HealthStatus = ({ className }: { className?: string }) => {
)}
</span>
</div>
{isMacOS && (
<div className="flex items-center gap-2">
{permissions && (
<span>
{permissions.accessibility ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<X className="h-4 w-4 text-red-500" />
)}
</span>
)}
<Button
variant="outline"
className="w-[260px] text-sm justify-start"
onClick={() => handlePermissionButton("accessibility")}
>
<Lock className="h-4 w-4 mr-2" />
grant accessibility permission
</Button>
</div>
)}
<div className="flex-shrink-0">
<PermissionButtons
type="accessibility"
settings={settings}
/>
</div>
</div>
)}
</div>
Expand Down
Loading

0 comments on commit de935b3

Please sign in to comment.