mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 13:23:28 +00:00
Fix Linux release (#2081)
* Fix Linux release - Pin appimage-builder to latest master - Add required cmp option to AppImageBuilder.yml - Disable intro video on Linux (it breaks onboarding for some reason) * Auto format * Fix typecheck
This commit is contained in:
parent
a18d60aa27
commit
7aae22e83f
|
@ -1 +1 @@
|
|||
Fork of [tauri-plugin-window-state]( https://github.com/tauri-apps/plugins-workspace/blob/v1/plugins/window-state).
|
||||
Fork of [tauri-plugin-window-state](https://github.com/tauri-apps/plugins-workspace/blob/v1/plugins/window-state).
|
||||
|
|
|
@ -109,7 +109,7 @@ function AppInner() {
|
|||
: Math.max(routerAtIndex.maxIndex, history.index)
|
||||
};
|
||||
|
||||
return [...routers]
|
||||
return [...routers];
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -148,7 +148,7 @@ function AppInner() {
|
|||
() => ({
|
||||
setTitle(id, title) {
|
||||
setTabs((tabs) => {
|
||||
const tabIndex = tabs.findIndex(t => t.id === id);
|
||||
const tabIndex = tabs.findIndex((t) => t.id === id);
|
||||
if (tabIndex === -1) return tabs;
|
||||
|
||||
tabs[tabIndex] = { ...tabs[tabIndex]!, title };
|
||||
|
|
|
@ -10,4 +10,4 @@ globalThis.rspcLinks = [
|
|||
];
|
||||
globalThis.onHotReload = (func: () => void) => {
|
||||
if (import.meta.hot) import.meta.hot.dispose(func);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { OperatingSystem, Platform } from '@sd/interface';
|
||||
import { dialog, invoke, os, shell } from '@tauri-apps/api';
|
||||
import { confirm } from '@tauri-apps/api/dialog';
|
||||
import { homeDir } from '@tauri-apps/api/path';
|
||||
import { open } from '@tauri-apps/api/shell';
|
||||
|
||||
// @ts-expect-error: Doesn't have a types package.
|
||||
import ConsistentHash from 'consistent-hash';
|
||||
import { OperatingSystem, Platform } from '@sd/interface';
|
||||
|
||||
import { commands, events } from './commands';
|
||||
import { env } from './env';
|
||||
|
@ -36,7 +35,6 @@ function constructServerUrl(urlSuffix: string) {
|
|||
if (!customUriServerUrl)
|
||||
throw new Error("'window.__SD_CUSTOM_URI_SERVER__' was not injected correctly!");
|
||||
|
||||
|
||||
hr = new ConsistentHash();
|
||||
customUriServerUrl.forEach((url) => hr.add(url));
|
||||
}
|
||||
|
|
|
@ -19,11 +19,7 @@ export function MobileDropdown() {
|
|||
return (
|
||||
<Dropdown.Root
|
||||
button={
|
||||
<Button
|
||||
aria-label="mobile-menu"
|
||||
className="hover:!bg-transparent"
|
||||
size="icon"
|
||||
>
|
||||
<Button aria-label="mobile-menu" className="hover:!bg-transparent" size="icon">
|
||||
<DotsThreeVertical weight="bold" className="h-6 w-6 " />
|
||||
</Button>
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const metroConfig = makeMetroConfig({
|
|||
resolver: {
|
||||
...expoDefaultConfig.resolver,
|
||||
extraNodeModules: {
|
||||
'react-native-svg': reactSVGPath,
|
||||
'react-native-svg': reactSVGPath
|
||||
},
|
||||
blockList: exclusionList([reactSVGExclude, rspcClientExclude, rspcReactExclude]),
|
||||
sourceExts: [...expoDefaultConfig.resolver.sourceExts, 'svg'],
|
||||
|
|
|
@ -67,7 +67,7 @@ const BrowseTags = () => {
|
|||
|
||||
return (
|
||||
<View style={tw`gap-5`}>
|
||||
<View style={tw`flex-row items-center justify-between w-full px-7`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between px-7`}>
|
||||
<Text style={tw`text-lg font-bold text-white`}>Tags</Text>
|
||||
<View style={tw`flex-row gap-3`}>
|
||||
<Pressable onPress={() => navigation.navigate('Tags')}>
|
||||
|
@ -81,7 +81,7 @@ const BrowseTags = () => {
|
|||
</Pressable>
|
||||
<Pressable testID="add-tag" onPress={() => modalRef.current?.present()}>
|
||||
<View
|
||||
style={tw`items-center justify-center w-8 h-8 bg-transparent border border-dashed rounded-md border-ink-faint`}
|
||||
style={tw`h-8 w-8 items-center justify-center rounded-md border border-dashed border-ink-faint bg-transparent`}
|
||||
>
|
||||
<Plus weight="bold" size={18} style={tw`text-ink-faint`} />
|
||||
</View>
|
||||
|
@ -96,7 +96,7 @@ const BrowseTags = () => {
|
|||
style={tw`relative h-auto w-[85.5vw] flex-col items-center justify-center overflow-hidden rounded-md border border-dashed border-sidebar-line p-4`}
|
||||
>
|
||||
<Icon name="Tags" size={38} />
|
||||
<Text style={tw`mt-2 font-medium text-center text-ink-dull`}>
|
||||
<Text style={tw`mt-2 text-center font-medium text-ink-dull`}>
|
||||
You have no tags
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -29,7 +29,7 @@ const CATEGORIES_LIST = [
|
|||
const Categories = () => {
|
||||
return (
|
||||
<View style={tw`relative gap-5`}>
|
||||
<Text style={tw`text-lg font-bold text-white px-7`}>Library</Text>
|
||||
<Text style={tw`px-7 text-lg font-bold text-white`}>Library</Text>
|
||||
<Fade width={30} height="100%" color="mobile-screen">
|
||||
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
|
||||
<View style={tw`flex-row gap-2 px-7`}>
|
||||
|
|
|
@ -10,7 +10,7 @@ import Fade from '../layout/Fade';
|
|||
const Jobs = () => {
|
||||
return (
|
||||
<View style={tw`gap-5`}>
|
||||
<View style={tw`flex-row items-center justify-between w-full px-7`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between px-7`}>
|
||||
<Text style={tw`text-lg font-bold text-white`}>Jobs</Text>
|
||||
</View>
|
||||
<Fade color="mobile-screen" height="100%" width={30}>
|
||||
|
@ -48,15 +48,15 @@ const Job = ({ progress, message, error }: JobProps) => {
|
|||
style={tw`h-[170px] w-[310px] flex-col rounded-md border border-app-line/50 bg-app-box/50`}
|
||||
>
|
||||
<View
|
||||
style={tw`flex-row items-center justify-between w-full px-5 py-2 border-b rounded-t-md border-sidebar-line/80 bg-mobile-header/50`}
|
||||
style={tw`w-full flex-row items-center justify-between rounded-t-md border-b border-sidebar-line/80 bg-mobile-header/50 px-5 py-2`}
|
||||
>
|
||||
<View style={tw`flex-row items-center gap-2`}>
|
||||
<FolderIcon size={36} />
|
||||
<Text style={tw`font-bold text-white text-md`}>Added Memories</Text>
|
||||
<Text style={tw`text-md font-bold text-white`}>Added Memories</Text>
|
||||
</View>
|
||||
<DotsThreeOutlineVertical weight="fill" size={20} color={tw.color('ink-faint')} />
|
||||
</View>
|
||||
<View style={tw`flex-row items-center justify-between flex-1 gap-5 px-5 py-3 mx-auto`}>
|
||||
<View style={tw`mx-auto flex-1 flex-row items-center justify-between gap-5 px-5 py-3`}>
|
||||
<AnimatedCircularProgress
|
||||
size={80}
|
||||
width={7}
|
||||
|
|
|
@ -78,8 +78,8 @@ export default function Header({
|
|||
Platform.OS === 'android' ? 'pt-5' : 'pt-10'
|
||||
)}
|
||||
>
|
||||
<View style={tw`justify-center w-full h-auto pb-5 mx-auto mt-5 px-7`}>
|
||||
<View style={tw`flex-row items-center justify-between w-full`}>
|
||||
<View style={tw`mx-auto mt-5 h-auto w-full justify-center px-7 pb-5`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between`}>
|
||||
<View style={tw`flex-row items-center gap-5`}>
|
||||
{navBack && (
|
||||
<Pressable
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function Search({ placeholder }: Props) {
|
|||
const searchStore = getSearchStore();
|
||||
return (
|
||||
<View
|
||||
style={tw`flex flex-row items-center justify-between w-full px-3 mt-4 border rounded-md shadow-sm h-11 border-sidebar-line bg-sidebar-button`}
|
||||
style={tw`mt-4 flex h-11 w-full flex-row items-center justify-between rounded-md border border-sidebar-line bg-sidebar-button px-3 shadow-sm`}
|
||||
>
|
||||
<TextInput
|
||||
onChangeText={(text) => searchStore.setSearch(text)}
|
||||
|
|
|
@ -24,10 +24,10 @@ export function SettingsItem(props: SettingsItemProps) {
|
|||
return (
|
||||
<Pressable onPress={props.onPress}>
|
||||
<View style={twStyle(' border-app-line/50 bg-app-box/50', borderRounded, border)}>
|
||||
<View style={tw`flex-row items-center h-auto`}>
|
||||
<View style={tw`h-auto flex-row items-center`}>
|
||||
{props.leftIcon && (
|
||||
<View
|
||||
style={tw`items-center justify-center w-8 h-8 ml-4 mr-5 border rounded-full bg-app-input border-app-line`}
|
||||
style={tw`ml-4 mr-5 h-8 w-8 items-center justify-center rounded-full border border-app-line bg-app-input`}
|
||||
>
|
||||
{props.leftIcon({ size: 20, color: tw.color('ink-dull') })}
|
||||
</View>
|
||||
|
|
|
@ -49,7 +49,7 @@ module.exports = {
|
|||
mobile: {
|
||||
header: `hsla(${DARK_HUE}, 15%, 10%, ${ALPHA})`,
|
||||
screen: `hsla(${DARK_HUE}, 15%, 12%, ${ALPHA})`,
|
||||
navtab: `hsla(${DARK_HUE}, 15%, 8%, ${ALPHA})`,
|
||||
navtab: `hsla(${DARK_HUE}, 15%, 8%, ${ALPHA})`
|
||||
},
|
||||
app: {
|
||||
DEFAULT: `hsla(${DARK_HUE}, 15%, 13%, ${ALPHA})`,
|
||||
|
@ -70,7 +70,7 @@ module.exports = {
|
|||
// menu
|
||||
menu: `hsla(${DARK_HUE}, 25%, 5%, ${ALPHA})`,
|
||||
// input
|
||||
input: `hsla(${DARK_HUE}, 15%, 20%, ${ALPHA})`,
|
||||
input: `hsla(${DARK_HUE}, 15%, 20%, ${ALPHA})`
|
||||
},
|
||||
sidebar: {
|
||||
box: `hsla(${DARK_HUE}, 15%, 16%, ${ALPHA})`,
|
||||
|
|
|
@ -8,12 +8,12 @@ module.exports = function (theme) {
|
|||
extend: {
|
||||
colors: theme ? COLORS[theme] : COLORS.dark,
|
||||
fontSize: {
|
||||
md: '16px',
|
||||
},
|
||||
md: '16px'
|
||||
}
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
extend: {}
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Themes } from '@sd/client';
|
||||
import { ComponentType, createElement, forwardRef } from 'react';
|
||||
import { create } from 'twrnc';
|
||||
import { Themes } from '@sd/client';
|
||||
|
||||
let tw = create(require('../constants/style/tailwind.js')());
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ const LocationItem: React.FC<LocationItemProps> = ({
|
|||
return (
|
||||
<Pressable onPress={onPress}>
|
||||
<View
|
||||
style={tw`flex-row justify-between w-full h-auto gap-3 p-2 border rounded-md border-sidebar-line/50 bg-sidebar-box`}
|
||||
style={tw`h-auto w-full flex-row justify-between gap-3 rounded-md border border-sidebar-line/50 bg-sidebar-box p-2`}
|
||||
>
|
||||
<View style={tw`flex-row items-center gap-2`}>
|
||||
<View style={tw`relative`}>
|
||||
|
@ -114,7 +114,7 @@ const LocationItem: React.FC<LocationItemProps> = ({
|
|||
<View style={tw`flex-row items-center gap-3`}>
|
||||
<View style={tw`rounded-md bg-app-input p-1.5`}>
|
||||
<Text
|
||||
style={tw`text-xs font-bold text-left text-ink-dull`}
|
||||
style={tw`text-left text-xs font-bold text-ink-dull`}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{`${byteSize(location.size_in_bytes)}`}
|
||||
|
|
|
@ -29,7 +29,7 @@ export function OnboardingContainer({ children }: React.PropsWithChildren) {
|
|||
)}
|
||||
>
|
||||
<Video
|
||||
style={tw`w-[700px] h-[700px]`}
|
||||
style={tw`h-[700px] w-[700px]`}
|
||||
shouldPlay
|
||||
onPlaybackStatusUpdate={(status) => {
|
||||
if (status.isLoaded && status.didJustFinish) {
|
||||
|
@ -50,22 +50,22 @@ export function OnboardingContainer({ children }: React.PropsWithChildren) {
|
|||
<CaretLeft size={24} weight="bold" color="white" />
|
||||
</Pressable>
|
||||
)}
|
||||
<View style={tw`z-10 items-center justify-center flex-1`}>
|
||||
<View style={tw`z-10 flex-1 items-center justify-center`}>
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
keyboardVerticalOffset={bottom}
|
||||
style={tw`items-center justify-center flex-1 w-full`}
|
||||
style={tw`w-full flex-1 items-center justify-center`}
|
||||
>
|
||||
<MotiView style={tw`items-center justify-center w-full px-4`}>
|
||||
<MotiView style={tw`w-full items-center justify-center px-4`}>
|
||||
{children}
|
||||
</MotiView>
|
||||
</KeyboardAvoidingView>
|
||||
<Text style={tw`absolute text-xs bottom-8 text-ink-dull/50`}>
|
||||
<Text style={tw`absolute bottom-8 text-xs text-ink-dull/50`}>
|
||||
© {new Date().getFullYear()} Spacedrive Technology Inc.
|
||||
</Text>
|
||||
</View>
|
||||
{/* Bloom */}
|
||||
<Image source={BloomOne} style={tw`absolute w-screen h-screen top-100 opacity-20`} />
|
||||
<Image source={BloomOne} style={tw`top-100 absolute h-screen w-screen opacity-20`} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ const GetStartedScreen = ({ navigation }: OnboardingStackScreenProps<'GetStarted
|
|||
{/* Get Started Button */}
|
||||
<FadeInUpAnimation delay={1200} style={tw`mt-8`}>
|
||||
<AnimatedButton variant="accent" onPress={() => navigation.push('NewLibrary')}>
|
||||
<Text style={tw`text-base font-medium text-center text-ink`}>Get Started</Text>
|
||||
<Text style={tw`text-center text-base font-medium text-ink`}>Get Started</Text>
|
||||
</AnimatedButton>
|
||||
</FadeInUpAnimation>
|
||||
</OnboardingContainer>
|
||||
|
|
|
@ -38,7 +38,7 @@ const LibraryGeneralSettingsScreen = (_: SettingsStackScreenProps<'LibraryGenera
|
|||
|
||||
return (
|
||||
<View style={tw`gap-4`}>
|
||||
<View style={tw`px-2 mt-4`}>
|
||||
<View style={tw`mt-4 px-2`}>
|
||||
<SettingsTitle>Name</SettingsTitle>
|
||||
<Controller
|
||||
name="name"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Tag, useCache, useLibraryQuery, useNodes } from '@sd/client';
|
||||
import { CaretRight, Pen, Trash } from 'phosphor-react-native';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Animated, FlatList, Text, View } from 'react-native';
|
||||
import { Swipeable } from 'react-native-gesture-handler';
|
||||
import { Tag, useCache, useLibraryQuery, useNodes } from '@sd/client';
|
||||
import { ModalRef } from '~/components/layout/Modal';
|
||||
import DeleteTagModal from '~/components/modal/confirmModals/DeleteTagModal';
|
||||
import CreateTagModal from '~/components/modal/tag/CreateTagModal';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { resetStore } from '@sd/client';
|
||||
import { proxy, useSnapshot } from 'valtio';
|
||||
import { proxySet } from 'valtio/utils';
|
||||
import { resetStore } from '@sd/client';
|
||||
|
||||
// TODO: Add "media"
|
||||
export type ExplorerLayoutMode = 'list' | 'grid' | "media"
|
||||
export type ExplorerLayoutMode = 'list' | 'grid' | 'media';
|
||||
|
||||
export type ExplorerKind = 'Location' | 'Tag' | 'Space';
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { proxy, useSnapshot } from "valtio";
|
||||
|
||||
import { proxy, useSnapshot } from 'valtio';
|
||||
|
||||
/**
|
||||
This is subject to change, but the idea is to have a global store for search
|
||||
|
@ -13,7 +12,7 @@ const searchStore = proxy({
|
|||
setSearch: (search: string) => {
|
||||
searchStore.search = search;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
export function useSearchStore() {
|
||||
return useSnapshot(searchStore);
|
||||
|
|
|
@ -3,100 +3,87 @@
|
|||
* If you rename or delete an asset you need to run `npx expo prebuild --clean` to delete them in your android and ios folder as well.
|
||||
*/
|
||||
|
||||
const {
|
||||
withDangerousMod,
|
||||
withXcodeProject,
|
||||
IOSConfig,
|
||||
} = require("@expo/config-plugins");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { withDangerousMod, withXcodeProject, IOSConfig } = require('@expo/config-plugins');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Specify the source directory of your assets
|
||||
const ASSET_SOURCE_DIR = "assets/rive";
|
||||
const ASSET_SOURCE_DIR = 'assets/rive';
|
||||
|
||||
const IOS_GROUP_NAME = "Rivassets";
|
||||
const IOS_GROUP_NAME = 'Rivassets';
|
||||
|
||||
const withRiveAssets = (config) => {
|
||||
config = addAndroidResources(config);
|
||||
config = addIOSResources(config);
|
||||
return config;
|
||||
config = addAndroidResources(config);
|
||||
config = addIOSResources(config);
|
||||
return config;
|
||||
};
|
||||
|
||||
// Code inspired by https://github.com/rive-app/rive-react-native/issues/185#issuecomment-1593396573
|
||||
function addAndroidResources(config) {
|
||||
return withDangerousMod(config, [
|
||||
"android",
|
||||
async (config) => {
|
||||
// Get the path to the Android project directory
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
return withDangerousMod(config, [
|
||||
'android',
|
||||
async (config) => {
|
||||
// Get the path to the Android project directory
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
|
||||
// Get the path to the Android resources directory
|
||||
const resDir = path.join(
|
||||
projectRoot,
|
||||
"android",
|
||||
"app",
|
||||
"src",
|
||||
"main",
|
||||
"res"
|
||||
);
|
||||
// Get the path to the Android resources directory
|
||||
const resDir = path.join(projectRoot, 'android', 'app', 'src', 'main', 'res');
|
||||
|
||||
// Create the 'raw' directory if it doesn't exist
|
||||
const rawDir = path.join(resDir, "raw");
|
||||
fs.mkdirSync(rawDir, { recursive: true });
|
||||
// Create the 'raw' directory if it doesn't exist
|
||||
const rawDir = path.join(resDir, 'raw');
|
||||
fs.mkdirSync(rawDir, { recursive: true });
|
||||
|
||||
// Get the path to the assets directory
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
// Get the path to the assets directory
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
|
||||
// Retrieve all files in the assets directory
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
// Retrieve all files in the assets directory
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
|
||||
// Move each asset file to the resources 'raw' directory
|
||||
for (const assetFile of assetFiles) {
|
||||
const srcAssetPath = path.join(assetSourcePath, assetFile);
|
||||
const destAssetPath = path.join(rawDir, assetFile);
|
||||
fs.copyFileSync(srcAssetPath, destAssetPath);
|
||||
}
|
||||
// Move each asset file to the resources 'raw' directory
|
||||
for (const assetFile of assetFiles) {
|
||||
const srcAssetPath = path.join(assetSourcePath, assetFile);
|
||||
const destAssetPath = path.join(rawDir, assetFile);
|
||||
fs.copyFileSync(srcAssetPath, destAssetPath);
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
]);
|
||||
return config;
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
// Code inspired by https://github.com/expo/expo/blob/61f8cf8d4b3cf5f8bf61f346476ebdb4aff40545/packages/expo-font/plugin/src/withFontsIos.ts
|
||||
function addIOSResources(config) {
|
||||
return withXcodeProject(config, async (config) => {
|
||||
const project = config.modResults;
|
||||
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
||||
return withXcodeProject(config, async (config) => {
|
||||
const project = config.modResults;
|
||||
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
||||
|
||||
// Create Assets group in project
|
||||
IOSConfig.XcodeUtils.ensureGroupRecursively(project, IOS_GROUP_NAME);
|
||||
// Create Assets group in project
|
||||
IOSConfig.XcodeUtils.ensureGroupRecursively(project, IOS_GROUP_NAME);
|
||||
|
||||
// Get riv filepaths
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
const assetFilesPaths = assetFiles.map(
|
||||
(assetFile) => `${assetSourcePath}/${assetFile}`
|
||||
);
|
||||
// Get riv filepaths
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
const assetFilesPaths = assetFiles.map((assetFile) => `${assetSourcePath}/${assetFile}`);
|
||||
|
||||
// Add assets to group
|
||||
addIOSResourceFile(project, platformProjectRoot, assetFilesPaths);
|
||||
// Add assets to group
|
||||
addIOSResourceFile(project, platformProjectRoot, assetFilesPaths);
|
||||
|
||||
return config;
|
||||
});
|
||||
return config;
|
||||
});
|
||||
|
||||
function addIOSResourceFile(project, platformRoot, assetFilesPaths) {
|
||||
for (const riveFile of assetFilesPaths) {
|
||||
const riveFilePath = path.relative(platformRoot, riveFile);
|
||||
IOSConfig.XcodeUtils.addResourceFileToGroup({
|
||||
filepath: riveFilePath,
|
||||
groupName: IOS_GROUP_NAME,
|
||||
project,
|
||||
isBuildFile: true,
|
||||
verbose: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
function addIOSResourceFile(project, platformRoot, assetFilesPaths) {
|
||||
for (const riveFile of assetFilesPaths) {
|
||||
const riveFilePath = path.relative(platformRoot, riveFile);
|
||||
IOSConfig.XcodeUtils.addResourceFileToGroup({
|
||||
filepath: riveFilePath,
|
||||
groupName: IOS_GROUP_NAME,
|
||||
project,
|
||||
isBuildFile: true,
|
||||
verbose: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = withRiveAssets;
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import clsx from 'clsx';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { byteSize, getItemFilePath, useSelector, type ExplorerItem, useLibraryQuery } from '@sd/client';
|
||||
|
||||
import {
|
||||
byteSize,
|
||||
getItemFilePath,
|
||||
useLibraryQuery,
|
||||
useSelector,
|
||||
type ExplorerItem
|
||||
} from '@sd/client';
|
||||
import { useLocale } from '~/hooks';
|
||||
|
||||
import { useExplorerContext } from '../../../Context';
|
||||
import { ExplorerDraggable } from '../../../ExplorerDraggable';
|
||||
import { ExplorerDroppable, useExplorerDroppableContext } from '../../../ExplorerDroppable';
|
||||
|
@ -110,7 +116,7 @@ const ItemMetadata = () => {
|
|||
selected={item.selected}
|
||||
/>
|
||||
<ItemSize />
|
||||
{item.data.type === "Label" && <LabelItemCount data={item.data} />}
|
||||
{item.data.type === 'Label' && <LabelItemCount data={item.data} />}
|
||||
</ExplorerDraggable>
|
||||
);
|
||||
};
|
||||
|
@ -148,23 +154,29 @@ const ItemSize = () => {
|
|||
);
|
||||
};
|
||||
|
||||
function LabelItemCount({data}: {data: Extract<ExplorerItem, {type: "Label"}>}) {
|
||||
function LabelItemCount({ data }: { data: Extract<ExplorerItem, { type: 'Label' }> }) {
|
||||
const { t } = useLocale();
|
||||
|
||||
const count = useLibraryQuery(["search.objectsCount", {
|
||||
filters: [{
|
||||
object: {
|
||||
labels: {
|
||||
in: [data.item.id]
|
||||
const count = useLibraryQuery([
|
||||
'search.objectsCount',
|
||||
{
|
||||
filters: [
|
||||
{
|
||||
object: {
|
||||
labels: {
|
||||
in: [data.item.id]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}])
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
if(count.data === undefined) return
|
||||
|
||||
return <div className="truncate rounded-md px-1.5 py-[1px] text-center text-tiny text-ink-dull">
|
||||
{t("item_with_count", {count: count.data})}
|
||||
</div>
|
||||
if (count.data === undefined) return;
|
||||
|
||||
return (
|
||||
<div className="truncate rounded-md px-1.5 py-[1px] text-center text-tiny text-ink-dull">
|
||||
{t('item_with_count', { count: count.data })}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ const NameCell = memo(({ item, selected }: { item: ExplorerItem; selected: boole
|
|||
<FileThumb
|
||||
data={item}
|
||||
frame
|
||||
frameClassName={clsx("!border", item.type === "Label" && "!rounded-lg")}
|
||||
frameClassName={clsx('!border', item.type === 'Label' && '!rounded-lg')}
|
||||
blackBars
|
||||
size={35}
|
||||
className={clsx('mr-2.5', cut && 'opacity-60')}
|
||||
|
|
|
@ -184,7 +184,7 @@ export const useViewItemDoubleClick = () => {
|
|||
}
|
||||
},
|
||||
[
|
||||
setSearchParams,
|
||||
setSearchParams,
|
||||
explorer.selectedItems,
|
||||
explorer.settingsStore.openOnDoubleClick,
|
||||
library.uuid,
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { Plus, X } from '@phosphor-icons/react';
|
||||
import { useSelector } from '@sd/client';
|
||||
import { Tooltip } from '@sd/ui';
|
||||
import clsx from 'clsx';
|
||||
import { useLayoutEffect, useRef } from 'react';
|
||||
import useResizeObserver from 'use-resize-observer';
|
||||
import { useRoutingContext } from '~/RoutingContext';
|
||||
import { useTabsContext } from '~/TabsContext';
|
||||
import { useSelector } from '@sd/client';
|
||||
import { Tooltip } from '@sd/ui';
|
||||
import {
|
||||
useKeyMatcher,
|
||||
useLocale,
|
||||
|
@ -13,6 +11,8 @@ import {
|
|||
useShortcut,
|
||||
useShowControls
|
||||
} from '~/hooks';
|
||||
import { useRoutingContext } from '~/RoutingContext';
|
||||
import { useTabsContext } from '~/TabsContext';
|
||||
|
||||
import { explorerStore } from '../Explorer/store';
|
||||
import { useTopBarContext } from './Layout';
|
||||
|
|
|
@ -65,7 +65,7 @@ export function Component() {
|
|||
center={<SearchBar />}
|
||||
left={
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<span className="text-sm font-medium truncate">Recents</span>
|
||||
<span className="truncate text-sm font-medium">Recents</span>
|
||||
</div>
|
||||
}
|
||||
right={<DefaultTopBarOptions />}
|
||||
|
|
|
@ -84,7 +84,7 @@ export default ({ redirectToSearch }: Props) => {
|
|||
<Input
|
||||
ref={searchRef}
|
||||
placeholder="Search"
|
||||
className="w-48 mx-2 transition-all duration-200 focus-within:w-60"
|
||||
className="mx-2 w-48 transition-all duration-200 focus-within:w-60"
|
||||
size="sm"
|
||||
value={value}
|
||||
onChange={(e) => {
|
||||
|
@ -98,7 +98,7 @@ export default ({ redirectToSearch }: Props) => {
|
|||
}}
|
||||
onFocus={() => search.setSearchBarFocused(true)}
|
||||
right={
|
||||
<div className="flex items-center space-x-1 pointer-events-none h-7 opacity-70 group-focus-within:hidden">
|
||||
<div className="pointer-events-none flex h-7 items-center space-x-1 opacity-70 group-focus-within:hidden">
|
||||
{
|
||||
<Shortcut
|
||||
chars={keybind([ModifierKeys.Control], ['F'])}
|
||||
|
|
|
@ -19,7 +19,7 @@ function Account() {
|
|||
return (
|
||||
<div className="my-2 flex w-full flex-col">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-semibold">{t("spacedrive_account")}</span>
|
||||
<span className="font-semibold">{t('spacedrive_account')}</span>
|
||||
<Button variant="gray" onClick={auth.logout}>
|
||||
{t('logout')}
|
||||
</Button>
|
||||
|
|
|
@ -23,7 +23,7 @@ export const Component = () => {
|
|||
<>
|
||||
<Heading
|
||||
title={t('backups')}
|
||||
description={t("backups_description")}
|
||||
description={t('backups_description')}
|
||||
rightArea={
|
||||
<div className="flex flex-row items-center space-x-5">
|
||||
<Button
|
||||
|
|
|
@ -3,7 +3,7 @@ import { RouteObject } from 'react-router';
|
|||
export default [
|
||||
{ path: 'general', lazy: () => import('./general') },
|
||||
{ path: 'account', lazy: () => import('./account') },
|
||||
{ path: 'usage', lazy: () => import('./usage')},
|
||||
{ path: 'usage', lazy: () => import('./usage') },
|
||||
{ path: 'appearance', lazy: () => import('./appearance') },
|
||||
{ path: 'keybindings', lazy: () => import('./keybindings') },
|
||||
{ path: 'extensions', lazy: () => import('./extensions') },
|
||||
|
|
|
@ -15,8 +15,8 @@ import Progress from './Progress';
|
|||
export const Component = () => {
|
||||
const os = useOperatingSystem(false);
|
||||
const debugState = useDebugState();
|
||||
// FIX-ME: Intro video breaks onboarding for the web version
|
||||
const [showIntro, setShowIntro] = useState(os !== 'browser');
|
||||
// FIX-ME: Intro video breaks onboarding for the web and Linux versions
|
||||
const [showIntro, setShowIntro] = useState(os === 'macOS' || os === 'windows');
|
||||
const ctx = useContextValue();
|
||||
|
||||
if (ctx.libraries.isLoading) return null;
|
||||
|
@ -46,19 +46,19 @@ export const Component = () => {
|
|||
</div>
|
||||
)}
|
||||
<DragRegion className="z-50 h-9" />
|
||||
<div className="flex flex-col gap-8 p-10 -mt-5 grow">
|
||||
<div className="flex flex-col items-center justify-center grow">
|
||||
<div className="-mt-5 flex grow flex-col gap-8 p-10">
|
||||
<div className="flex grow flex-col items-center justify-center">
|
||||
<Outlet />
|
||||
</div>
|
||||
<Progress />
|
||||
</div>
|
||||
<div className="flex justify-center p-4">
|
||||
<p className="text-xs opacity-50 text-ink-dull">
|
||||
<p className="text-xs text-ink-dull opacity-50">
|
||||
© {new Date().getFullYear()} Spacedrive Technology Inc.
|
||||
</p>
|
||||
</div>
|
||||
<div className="absolute -z-10">
|
||||
<div className="relative w-screen h-screen">
|
||||
<div className="relative h-screen w-screen">
|
||||
<img src={BloomOne} className="absolute h-[2000px] w-[2000px]" />
|
||||
{/* <img src={BloomThree} className="absolute w-[2000px] h-[2000px] -right-[200px]" /> */}
|
||||
</div>
|
||||
|
|
|
@ -388,10 +388,15 @@ body {
|
|||
}
|
||||
|
||||
@keyframes wiggle {
|
||||
0%, 100% { transform: rotate(-1deg); }
|
||||
50% { transform: rotate(1deg); }
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(-1deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(1deg);
|
||||
}
|
||||
}
|
||||
|
||||
.wiggle {
|
||||
animation: wiggle 200ms infinite;
|
||||
animation: wiggle 200ms infinite;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
//@ts-nocheck
|
||||
|
||||
// WARNING: Import order matters
|
||||
|
||||
window.Prism = window.Prism || {};
|
||||
Prism.manual = true;
|
||||
|
||||
export { highlightElement } from "prismjs";
|
||||
|
||||
// Languages
|
||||
// Do not include default ones: markup, html, xml, svg, mathml, ssml, atom, rss, css, clike, javascript, js
|
||||
import 'prismjs/components/prism-applescript.js';
|
||||
|
@ -58,3 +49,11 @@ import 'prismjs/components/prism-vala.js';
|
|||
import 'prismjs/components/prism-yaml.js';
|
||||
import 'prismjs/components/prism-zig.js';
|
||||
|
||||
//@ts-nocheck
|
||||
|
||||
// WARNING: Import order matters
|
||||
|
||||
window.Prism = window.Prism || {};
|
||||
window.Prism.manual = true;
|
||||
|
||||
export { highlightElement } from 'prismjs';
|
||||
|
|
|
@ -39,7 +39,8 @@ export function getExplorerItemData(data?: ExplorerItem | null): ItemData {
|
|||
const object = getItemObject(data);
|
||||
|
||||
if (object?.kind) itemData.kind = ObjectKind[object?.kind] ?? 'Unknown';
|
||||
else if(data.type === "NonIndexedPath") itemData.kind = ObjectKind[data.item.kind] ?? 'Unknown';
|
||||
else if (data.type === 'NonIndexedPath')
|
||||
itemData.kind = ObjectKind[data.item.kind] ?? 'Unknown';
|
||||
|
||||
// Objects only have dateCreated and dateAccessed
|
||||
itemData.dateCreated = object?.date_created ?? null;
|
||||
|
|
|
@ -11,8 +11,7 @@ let permits = 0; // A Mutex in JS, lmao
|
|||
|
||||
export const getPermits = () => permits;
|
||||
|
||||
if ("onHotReload" in globalThis)
|
||||
globalThis?.onHotReload(() => (permits = 0));
|
||||
if ('onHotReload' in globalThis) globalThis?.onHotReload(() => (permits = 0));
|
||||
|
||||
// A query where the data is streamed in.
|
||||
// Also basically a subscription with support for React Suspense and proper loading states, invalidation, etc.
|
||||
|
|
|
@ -11,7 +11,7 @@ export enum ModifierKeys {
|
|||
NumLock = 'NumLock',
|
||||
ScrollLock = 'ScrollLock',
|
||||
Symbol = 'Symbol',
|
||||
SymbolLock = 'SymbolLock',
|
||||
SymbolLock = 'SymbolLock'
|
||||
}
|
||||
|
||||
export enum EditingKeys {
|
||||
|
@ -20,14 +20,14 @@ export enum EditingKeys {
|
|||
}
|
||||
|
||||
export enum UIKeys {
|
||||
Escape = 'Escape',
|
||||
Escape = 'Escape'
|
||||
}
|
||||
|
||||
export enum NavigationKeys {
|
||||
ArrowUp = 'ArrowUp',
|
||||
ArrowDown = 'ArrowDown',
|
||||
ArrowLeft = 'ArrowLeft',
|
||||
ArrowRight = 'ArrowRight',
|
||||
ArrowRight = 'ArrowRight'
|
||||
}
|
||||
|
||||
export type OSforKeys = 'macOS' | 'Windows' | 'Other';
|
||||
|
@ -54,7 +54,7 @@ export const modifierSymbols: Record<
|
|||
ArrowUp: { Other: '↑' },
|
||||
ArrowDown: { Other: '↓' },
|
||||
ArrowLeft: { Other: '←' },
|
||||
ArrowRight: { Other: '→' },
|
||||
ArrowRight: { Other: '→' }
|
||||
};
|
||||
|
||||
export const keySymbols: Record<string, { macOS?: string; Windows?: string; Other: string }> = {
|
||||
|
|
|
@ -161,5 +161,6 @@ AppDir:
|
|||
|
||||
AppImage:
|
||||
arch: !ENV '${TARGET_APPIMAGE_ARCH}'
|
||||
comp: xz
|
||||
sign-key: None
|
||||
update-information: None
|
||||
|
|
|
@ -21,6 +21,7 @@ This directory contains the script and recipe to build an AppImage from a Spaced
|
|||
- Execute the `build_appimage.sh` script inside a `debian:bookworm` container
|
||||
|
||||
- Podman: `podman run --rm -v "$(CDPATH='' cd ../.. && pwd -P):/srv" -w /srv debian:bookworm scripts/appimage/build_appimage.sh`
|
||||
|
||||
- You may have to run Podman with `podman run --privileged` if you get a permission denied error
|
||||
|
||||
- Docker: `docker run --rm -v "$(CDPATH='' cd ../.. && pwd -P):/srv" -w /srv debian:bookworm scripts/appimage/build_appimage.sh`
|
||||
|
|
|
@ -70,7 +70,7 @@ if ! command -v appimage-builder >/dev/null 2>&1; then
|
|||
pip3 install wheel setuptools --upgrade
|
||||
|
||||
echo 'Install appimage-build in temporary Python virtual environment...'
|
||||
pip3 install git+https://github.com/AppImageCrafters/appimage-builder.git
|
||||
pip3 install git+https://github.com/AppImageCrafters/appimage-builder.git@61c8ddde9ef44b85d7444bbe79d80b44a6a5576d
|
||||
fi
|
||||
|
||||
echo 'Running appimage-builder...'
|
||||
|
|
Loading…
Reference in a new issue