Skip to content

Commit

Permalink
Profile editing workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
undyingwraith committed May 8, 2024
1 parent e88a96e commit ce72c23
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 42 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.formatOnSave": true,
"editor.detectIndentation": false,
"editor.insertSpaces": false
"editor.insertSpaces": false,
"typescript.format.semicolons": "insert"
}
43 changes: 43 additions & 0 deletions packages/core/src/components/molecules/ProfileEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import { useComputed, useSignal } from "@preact/signals-react";
import { Button, Card, CardActions, CardContent, CardHeader, TextField } from "@mui/material";
import { IConfigurationService } from '../../service';
import { useTranslation } from 'react-i18next';

export function ProfileEditor(props: { id: string, configService: IConfigurationService, onCancel: () => void, onSave: () => void }) {
const { configService, id, onCancel, onSave } = props;
const [_t] = useTranslation();

const profile = useComputed(() => {
return configService.getProfile(id);
});

const name = useSignal<string>(profile.value?.name ?? id);

function save() {
configService.setProfile(id, {
...(profile.value ?? {}),
name: name.value,
});
onSave();
}

return (
<Card>
<CardHeader title={_t('EditProfile')} />
<CardContent>
<TextField
label={_t('Name')}
value={name}
onChange={(ev) => {
name.value = ev.target.value;
}}
/>
</CardContent>
<CardActions>
<Button onClick={() => onCancel()}>{_t('Cancel')}</Button>
<Button onClick={() => save()}>{_t('Save')}</Button>
</CardActions>
</Card>
);
}
75 changes: 51 additions & 24 deletions packages/core/src/components/molecules/ProfileSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,78 @@
import { Button, ButtonGroup, Card, CardActions, CardHeader, Dialog, Stack } from "@mui/material";
import { useComputed, useSignal } from "@preact/signals-react";
import React from "react";
import { IConfigurationService, IProfile } from "../../service";
import { CardActions, Button, ButtonGroup, Card, CardContent, Stack, Dialog, DialogTitle, DialogContent, DialogActions } from "@mui/material";
import { useTranslation } from "react-i18next";
import { useComputed, useSignal } from "@preact/signals-react";
import { IConfigurationService, IProfile } from "../../service";
import { uuid } from '../../util';
import { ProfileEditor } from "./ProfileEditor";

export function ProfileSelector(props: { profile?: IProfile, profiles: string[], switchProfile: (name: string) => void, configService: IConfigurationService }) {
export function ProfileSelector(props: { profile?: IProfile, switchProfile: (name: string) => void, configService: IConfigurationService; }) {
const { configService } = props;

const [_t] = useTranslation();
const editing = useSignal<string | undefined>(undefined);
const profiles = useSignal<(IProfile & { id: string; })[]>(loadProfiles());

function loadProfiles() {
return configService.getProfiles().map(p => ({
...configService.getProfile(p),
id: p,
}));
}

const dialog = useComputed(() => {
if (editing.value !== undefined) {
if (editing.value == undefined) {
return <></>;
}
return (
<Dialog
open={true}
onClose={() => editing.value = undefined}
>
<DialogTitle>{_t('EditProfile')}</DialogTitle>
<DialogContent>
TODO
</DialogContent>
<DialogActions>
<Button onClick={() => editing.value = undefined}>{_t('Cancel')}</Button>
<Button>{_t('Save')}</Button>
</DialogActions>
<ProfileEditor
id={editing.value}
configService={configService}
onCancel={() => editing.value = undefined}
onSave={() => {
editing.value = undefined;
profiles.value = loadProfiles();
}}
/>
</Dialog>
);
});

const content = useComputed(() => profiles.value.map(p => (
<Card key={p.id}>
<CardHeader title={p.name} subheader={p.id} />
<CardActions>
<ButtonGroup>
<Button
color={"error"}
onClick={() => {
configService.removeProfile(p.id);
profiles.value = loadProfiles();
}}
>{_t('Delete')}</Button>
<Button
onClick={() => editing.value = p.id}
>{_t('Edit')}</Button>
<Button
variant={'contained'}
onClick={() => props.switchProfile(p.id)}
>{_t('Start')}</Button>
</ButtonGroup>
</CardActions>
</Card>
)));

return (<>
<Stack spacing={1}>
{props.profiles.map(p => <Card key={p}>
<CardContent>{p}</CardContent>
<CardActions>
<ButtonGroup>
<Button onClick={() => editing.value = p}>{_t('Edit')}</Button>
<Button onClick={() => props.switchProfile(p)}>{_t('Start')}</Button>
</ButtonGroup>
</CardActions>
</Card>)}
{content}
<div>
<Button onClick={() => editing.value = ''}>{_t('AddProfile')}</Button>
<Button onClick={() => editing.value = uuid()}>{_t('AddProfile')}</Button>
</div>
</Stack>
{dialog}
</>);
}
}
4 changes: 2 additions & 2 deletions packages/core/src/components/pages/AppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function AppContextProvider(props: PropsWithChildren<IAppInit>) {
const node = useSignal<IIpfsService | undefined>(undefined);
const state = useSignal<LoadState>(LoadState.Idle);

const accentColor = useComputed(() => '#0b3a53');
const accentColor = useComputed(() => '#6200EE');
const darkMode = useComputed(() => true);
const theme = useComputed(() => darkMode.value ? createDarkTheme(accentColor.value) : createLightTheme(accentColor.value));

Expand Down Expand Up @@ -82,7 +82,7 @@ export function AppContextProvider(props: PropsWithChildren<IAppInit>) {
case LoadState.Idle:
return (
<Box>
<ProfileSelector switchProfile={start} profiles={props.configService.getProfiles()} configService={configService} />
<ProfileSelector switchProfile={start} configService={props.configService} />
</Box>
);
case LoadState.Starting:
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export type {
IInternalProfile,
IRemoteProfile,
} from './service';
export { uuid } from './util';
12 changes: 9 additions & 3 deletions packages/core/src/service/IConfigurationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ export interface IConfigurationService {
/**
* Gets a list of all profile names.
*/
getProfiles(): string[]
getProfiles(): string[];

/**
* returns the specified Profile
* returns the specified Profile.
* @param name name of the profile
*/
getProfile(name: string): IProfile;

/**
* Updates the specified Profile
* Updates the specified Profile.
* @param name name of the profile
* @param profile updated profile
*/
setProfile(name: string, profile: IProfile): void;

/**
* Deletes the specified Profile.
* @param name name of the profile
*/
removeProfile(name: string): void;
}
4 changes: 3 additions & 1 deletion packages/core/src/translations/de.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"AddProfile": "Profil hinzufügen",
"Cancel": "Abbrechen",
"Delete": "Löschen",
"Edit": "Bearbeiten",
"EditProfile": "Profil bearbeiten",
"Home": "Home",
"Loading": "Laden...",
"Logout": "Abmelden",
"Movies": "Filme",
"Name": "Name",
"Save": "Speichern",
"Search": "Suche",
"Start": "Starten",
"Starting": "Starten...",
"Stopping": "Stoppen...",
"SwarmKey": "Schwarm Schlüssel"
}
}
4 changes: 3 additions & 1 deletion packages/core/src/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"AddProfile": "Add profile",
"Cancel": "Cancel",
"Delete": "Delete",
"Edit": "Edit",
"EditProfile": "Edit profile",
"Home": "Home",
"Loading": "Loading...",
"Logout": "Logout",
"Movies": "Movies",
"Name": "Name",
"Save": "Save",
"Search": "Search",
"Start": "Start",
"Starting": "Starting node...",
"Stopping": "Stopping node...",
"SwarmKey": "Swarm Key"
}
}
5 changes: 5 additions & 0 deletions packages/core/src/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function uuid() {
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
(+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16)
);
}
17 changes: 10 additions & 7 deletions packages/desktop/src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import fs from 'fs';
import { IConfigurationService, INodeService, IInternalProfile, IProfile, IIpfsService, IFileInfo } from 'ipmc-core';

function getProfileFolder(name: string): string {
return `./profiles/${name}`
return `./profiles/${name}`;
}

const nodeService: INodeService = {
Expand Down Expand Up @@ -94,7 +94,7 @@ const nodeService: INodeService = {
const port = connString.substring(connString.lastIndexOf('/') + 1);
return {
async ls(cid: string) {
const files: IFileInfo[] = []
const files: IFileInfo[] = [];
for await (const file of node.ls(cid)) {
files.push({
type: file.type,
Expand All @@ -113,14 +113,14 @@ const nodeService: INodeService = {
async peers() {
return (await node.swarm.peers()).map(p => p.addr.toString());
}
}
};
}
};

const configService: IConfigurationService = {
getProfiles(): string[] {
try {
const profiles = fs.readdirSync('./profiles')
const profiles = fs.readdirSync('./profiles');
return profiles;
} catch (_) {
return [];
Expand All @@ -132,6 +132,9 @@ const configService: IConfigurationService = {
setProfile(name: string, profile: IProfile) {
fs.writeFileSync(getProfileFolder(name) + '/profile.json', JSON.stringify(profile));
},
removeProfile(name) {
fs.rmdirSync(getProfileFolder(name), { recursive: true });
},
};

// Use `contextBridge` APIs to expose Electron APIs to
Expand All @@ -144,14 +147,14 @@ if (process.contextIsolated) {
contextBridge.exposeInMainWorld('configService', configService);
console.log("exposeInMainWorld");
} catch (error) {
console.error(error)
console.error(error);
}
} else {
console.log("window");
// @ts-ignore (define in dts)
//window.electron = electronAPI
// @ts-ignore (define in dts)
window.configService = configService
window.configService = configService;
// @ts-ignore (define in dts)
window.nodeService = nodeService
window.nodeService = nodeService;
}
12 changes: 9 additions & 3 deletions packages/webui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export function App() {
window.localStorage.setItem('profiles', JSON.stringify([...profiles, name]));
}
},
removeProfile(name) {
window.localStorage.removeItem('profile_' + name);
const value = window.localStorage.getItem('profiles');
const profiles: string[] = value ? JSON.parse(value) : [];
window.localStorage.setItem('profiles', JSON.stringify(profiles.filter(p => p !== name)));
},
}}
nodeService={{
async create(profile) {
Expand Down Expand Up @@ -105,7 +111,7 @@ export function App() {
const port = connString.substring(connString.lastIndexOf('/') + 1);
return {
async ls(cid: string) {
const files: IFileInfo[] = []
const files: IFileInfo[] = [];
for await (const file of node.ls(cid)) {
files.push({
type: file.type,
Expand All @@ -124,8 +130,8 @@ export function App() {
peers() {
return node.swarm.peers().then(r => r.map(p => p.addr.toString()));
}
}
};
},
}}
/>
/>;
};

0 comments on commit ce72c23

Please sign in to comment.