Files
spacedrive/interface/util/Platform.tsx
Oscar Beaumont fbac1e6fc5 [ENG-1508] Launch Spacedrop (#1893)
* Shit UI

* refactor a bit

* wip

* yeet

* farming the wry but it's stale

* Real-time hover event

* Hook with `Platform` + fix broken window-state plugin

* `DragAndDropDebug`

* Clippy

* revert Tauri v2 stuff

* minor

* probs not gonna work

* undo last commit

* a

* b

* c

* d

* e

* f

* g

* long shot

* 1

* no 7

* da hell

* large bruh moment

* lol

* zzzz

* SSH into CI

* yeet

* Tauri mouse position without new Wry

* go for gold

* Correctly lock `ort` version

* minor fixes

* debounce hover events

* WTF Tauri

* Replace DND hooks with goated versions

* wip frontend stuff

* fix ts

* disable library p2p stuff

* remove Spacedrop dialog + hook up backend

* `useOnDndLeave` working

* Close popover when drag outside

* Allow `openFilePickerDialog` for Spacedrop

* couple of fixes

* empty state

* smh

---------

Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2024-01-08 06:42:17 +00:00

97 lines
3.7 KiB
TypeScript

import { createContext, useContext, type PropsWithChildren } from 'react';
import { auth } from '@sd/client';
export type OperatingSystem = 'browser' | 'linux' | 'macOS' | 'windows' | 'unknown';
// This is copied from the Tauri Specta output.
// It will only exist on desktop
export type DragAndDropEvent =
| { type: 'Hovered'; paths: string[]; x: number; y: number }
| { type: 'Dropped'; paths: string[]; x: number; y: number }
| { type: 'Cancelled' };
// Platform represents the underlying native layer the app is running on.
// This could be Tauri or web.
export type Platform = {
platform: 'web' | 'tauri'; // This represents the specific platform implementation
getThumbnailUrlByThumbKey: (thumbKey: string[]) => string;
getFileUrl: (libraryId: string, locationLocalId: number, filePathId: number) => string;
getFileUrlByPath: (path: string) => string;
openLink: (url: string) => void;
// Tauri patches `window.confirm` to return `Promise` not `bool`
confirm(msg: string, cb: (result: boolean) => void): void;
getOs?(): Promise<OperatingSystem>;
openDirectoryPickerDialog?(opts?: { title?: string; multiple: false }): Promise<null | string>;
openDirectoryPickerDialog?(opts?: {
title?: string;
multiple?: boolean;
}): Promise<null | string | string[]>;
openFilePickerDialog?(): Promise<null | string | string[]>;
saveFilePickerDialog?(opts?: { title?: string; defaultPath?: string }): Promise<string | null>;
showDevtools?(): void;
openPath?(path: string): void;
openLogsDir?(): void;
userHomeDir?(): Promise<string>;
// Opens a file path with a given ID
openFilePaths?(library: string, ids: number[]): any;
openEphemeralFiles?(paths: string[]): any;
revealItems?(
library: string,
items: (
| { Location: { id: number } }
| { FilePath: { id: number } }
| { Ephemeral: { path: string } }
)[]
): Promise<unknown>;
requestFdaMacos?(): void;
getFilePathOpenWithApps?(library: string, ids: number[]): Promise<unknown>;
reloadWebview?(): Promise<unknown>;
getEphemeralFilesOpenWithApps?(paths: string[]): Promise<unknown>;
openFilePathWith?(library: string, fileIdsAndAppUrls: [number, string][]): Promise<unknown>;
openEphemeralFileWith?(pathsAndUrls: [string, string][]): Promise<unknown>;
refreshMenuBar?(): Promise<unknown>;
setMenuBarItemState?(id: string, enabled: boolean): Promise<unknown>;
lockAppTheme?(themeType: 'Auto' | 'Light' | 'Dark'): any;
subscribeToDragAndDropEvents?(callback: (event: DragAndDropEvent) => void): Promise<() => void>;
updater?: {
useSnapshot: () => UpdateStore;
checkForUpdate(): Promise<Update | null>;
installUpdate(): Promise<any>;
runJustUpdatedCheck(onViewChangelog: () => void): Promise<void>;
};
auth: auth.ProviderConfig;
landingApiOrigin: string;
};
export type Update = { version: string; body: string | null };
export type UpdateStore =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'error' }
| { status: 'updateAvailable'; update: Update }
| { status: 'noUpdateAvailable' }
| { status: 'installing' };
// Keep this private and use through helpers below
const context = createContext<Platform>(undefined!);
// is a hook which allows you to fetch information about the current platform from the React context.
export function usePlatform(): Platform {
const ctx = useContext(context);
if (!ctx)
throw new Error(
"The 'PlatformProvider' has not been mounted above the current 'usePlatform' call."
);
return ctx;
}
// provides the platform context to the rest of the app through React context.
// Mount it near the top of your component tree.
export function PlatformProvider({
platform,
children
}: PropsWithChildren<{ platform: Platform }>) {
return <context.Provider value={platform}>{children}</context.Provider>;
}