Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- feature: ui improvements after rewrite #35

Merged
merged 12 commits into from
Oct 10, 2023
Merged
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nx/typescript"],
"rules": {}
"rules": {
"react/no-unknown-property": ["error", { "ignore": ["cmdk-input-wrapper"] }]
}
},
{
"files": ["*.js", "*.jsx"],
Expand Down
2 changes: 1 addition & 1 deletion apps/shinkai-visor/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"ignorePatterns": ["!**/*", "dist"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
Expand Down
12 changes: 2 additions & 10 deletions apps/shinkai-visor/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,14 @@
}
],
"commands": {
"_execute_action": {
"suggested_key": {
"windows": "Ctrl+Shift+U",
"mac": "Ctrl+Shift+U",
"chromeos": "Ctrl+Shift+U",
"linux": "Ctrl+Shift+U"
}
},
"command-launcher": {
"toggle-popup": {
"suggested_key": {
"windows": "Ctrl+Comma",
"mac": "Command+Comma",
"chromeos": "Ctrl+Comma",
"linux": "Ctrl+Comma"
},
"description": "UV command launcher"
"description": "Open/Close Shinkai popup"
}
},
"permissions": ["storage", "contextMenus"],
Expand Down
21 changes: 13 additions & 8 deletions apps/shinkai-visor/src/components/action-button/action-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';

import shinkaiLogo from '../../assets/icons/shinkai-min.svg';
import { cn } from '../../helpers/cn-utils';
import { srcUrlResolver } from '../../helpers/src-url-resolver';
import { useGlobalActionButtonChromeMessage } from '../../hooks/use-global-action-button-chrome-message';
import { langMessages, locale } from '../../lang/intl';
Expand All @@ -32,25 +33,29 @@ export const ActionButton = () => {
const togglePopupVisibility = () => {
sendContentScriptMessage({
type: ContentScriptMessageType.TogglePopupVisibility,
data: !popupVisibility,
});
};
return (
<div className="p-2" onClick={() => togglePopupVisibility()}>
<div
className={cn(
'p-1 w-[50px] h-[50px] flex flex-col space-y-1 items-center justify-center',
!popupVisibility && 'animate-pulse'
)}
onClick={() => togglePopupVisibility()}
>
<motion.div
animate={{
rotate: popupVisibility ? -22 : 0,
}}
className="block"
className="w-4 h-4"
>
<img
alt="shinkai-app-logo"
className={`w-full h-full ${
popupVisibility ? '-rotate-[22deg]' : 'animate-pulse'
}`}
className={"w-full h-full"}
src={srcUrlResolver(shinkaiLogo)}
/>
</motion.div>
<span className="text-xs text-center">⌘ + ,</span>
</div>
);
};
Expand All @@ -63,11 +68,11 @@ root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={storePersistor}>
<IntlProvider locale={locale} messages={langMessages}>
<div className="fixed w-[50px] h-[50px] top-32 right-2 overflow-hidden bg-background z-[1500000000] border-solid border-primary border-2 rounded-lg">
<div className="fixed top-32 right-2 overflow-hidden bg-background z-[1500000000] border-solid border-primary border-2 rounded-lg">
<ActionButton></ActionButton>
</div>
</IntlProvider>
</PersistGate>
</Provider>
</React.StrictMode>,
</React.StrictMode>
);
6 changes: 2 additions & 4 deletions apps/shinkai-visor/src/components/add-agent/add-agent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,9 @@ export const AddAgent = () => {
const {
mutateAsync: createAgent,
isLoading,
isError,
error,
} = useCreateAgent({
onSuccess: () => {
history.replace('/agents');
onSuccess: (data) => {
history.replace({ pathname: '/inboxes/create-job' });
},
});

Expand Down
32 changes: 24 additions & 8 deletions apps/shinkai-visor/src/components/add-node/add-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ import {
import { Input } from '../ui/input';

const formSchema = z.object({
registrationCode: z.string().nonempty(),
registrationCode: z.string().optional(),
registrationName: z.string().nonempty(),
permissionType: z.enum(['admin']),
identityType: z.enum(['device']),
profile: z.enum(['main']),
nodeAddress: z.string().url(),
shinkaiIdentity: z.string().nonempty(),
nodeEncryptionPublicKey: z.string().nonempty(),
nodeSignaturePublicKey: z.string().nonempty(),
nodeEncryptionPublicKey: z.string().optional(),
nodeSignaturePublicKey: z.string().optional(),
profileEncryptionPublicKey: z.string().nonempty(),
profileSignaturePublicKey: z.string().nonempty(),
myDeviceEncryptionPublicKey: z.string().nonempty(),
Expand Down Expand Up @@ -66,6 +66,9 @@ enum AddNodeSteps {
export const AddNode = () => {
const history = useHistory();
const setAuth = useAuth((state) => state.setAuth);
const DEFAULT_NODE_ADDRESS = 'http://127.0.0.1:9550';
// TODO: This value should be obtained from node
const DEFAULT_SHINKAI_IDENTITY = '@@node1.shinkai';
const form = useForm<FormType>({
resolver: zodResolver(formSchema),
defaultValues: {
Expand Down Expand Up @@ -100,8 +103,8 @@ export const AddNode = () => {
permission_type: values.permissionType,
node_address: values.nodeAddress,
shinkai_identity: values.shinkaiIdentity,
node_signature_pk: response.data?.identity_public_key ?? values.nodeSignaturePublicKey,
node_encryption_pk: response.data?.encryption_public_key ?? values.nodeEncryptionPublicKey,
node_signature_pk: response.data?.identity_public_key ?? values.nodeSignaturePublicKey ?? '',
node_encryption_pk: response.data?.encryption_public_key ?? values.nodeEncryptionPublicKey ?? '',
registration_name: values.registrationName,
my_device_identity_pk: values.myDeviceIdentityPublicKey,
my_device_identity_sk: values.myDeviceIdentitySharedKey,
Expand Down Expand Up @@ -204,15 +207,14 @@ export const AddNode = () => {
};

const connect = (values: FormType) => {
console.log('values', values);
submitRegistration({
registration_code: values.registrationCode,
registration_code: values.registrationCode ?? '',
profile: values.profile,
identity_type: values.identityType,
permission_type: values.permissionType,
node_address: values.nodeAddress,
shinkai_identity: values.shinkaiIdentity,
node_encryption_pk: values.nodeEncryptionPublicKey,
node_encryption_pk: values.nodeEncryptionPublicKey ?? '',
registration_name: values.registrationName,
my_device_identity_sk: values.myDeviceIdentitySharedKey,
my_device_encryption_sk: values.myDeviceEncryptionSharedKey,
Expand Down Expand Up @@ -245,8 +247,22 @@ export const AddNode = () => {
);
}, [form]);

useEffect(() => {
fetch(`${DEFAULT_NODE_ADDRESS}/v1/shinkai_health`)
.then((response) => response.json())
.then((data) => {
if (data.status === 'ok') {
form.setValue('nodeAddress', DEFAULT_NODE_ADDRESS);
form.setValue('shinkaiIdentity', DEFAULT_SHINKAI_IDENTITY);
setCurrentStep(AddNodeSteps.Connect)
}
})
.catch((error) => console.error('error polling', error));
}, [form]);

return (
<div className="h-full flex flex-col space-y-3">
<span className='text-xl'>Connect</span>
<div className="h-full flex flex-col grow place-content-center">
{currentStep === AddNodeSteps.ScanQR && (
<div className="h-full flex flex-col space-y-3 justify-between">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const CreateJob = () => {
if (!auth) return;
let content = values.content;
if (query.has('context')) {
content = `${values.content} - ${query.get('context')}`;
content = `${values.content} - \`\`\`${query.get('context')}\`\`\``;
}
createJob({
shinkaiIdentity: auth.shinkai_identity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const InboxInput = (props: InboxInputProps) => {
<FormItem>
<FormControl>
<Input
disabled={props.loading}
placeholder={intl.formatMessage({
id: 'tmwtd',
})}
Expand Down
20 changes: 3 additions & 17 deletions apps/shinkai-visor/src/components/inbox/inbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export const Inbox = () => {
const getAvatar = (message: ShinkaiMessage) => {
return isLocalMessage(
message,
auth?.profile || '',
auth?.registration_name || ''
auth?.shinkai_identity || '',
auth?.profile || ''
)
? 'https://ui-avatars.com/api/?name=Me&background=FE6162&color=fff'
: 'https://ui-avatars.com/api/?name=O&background=363636&color=fff';
Expand Down Expand Up @@ -174,28 +174,14 @@ export const Inbox = () => {
))}
{isChatConversationSuccess &&
data?.pages?.map((group, index) => (
// <div
// className={`flex w-max max-w-[75%] flex-col gap-2 rounded-b-lg px-3 py-2 text-sm bg-muted ${
// isLocalMessage(
// message,
// setup.data?.nodeData?.shinkaiIdentity || '',
// setup.data?.nodeData.profile || '',
// )
// ? 'ml-auto bg-primary text-primary-foreground rounded-l-lg'
// : 'rounded-r-lg'
// }`}
// key={message.external_metadata?.scheduled_time}
// >
// {getMessageContent(message)}
// </div>
<Fragment key={index}>
{Object.entries(groupMessagesByDate(group)).map(
([date, messages]) => {
return (
<div key={date}>
<div
className={cn(
'relative z-10 m-auto flex w-[140px] items-center justify-center rounded-xl bg-slate-900 shadow-lg transition-opacity',
'relative z-10 m-auto flex w-[140px] items-center justify-center rounded-xl bg-white shadow-lg transition-opacity',
true && 'sticky top-5'
)}
>
Expand Down
49 changes: 37 additions & 12 deletions apps/shinkai-visor/src/components/inboxes/inboxes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import './inboxes.css';

import { useGetInboxes } from '@shinkai_network/shinkai-node-state/lib/queries/getInboxes/useGetInboxes';
import { Bot } from 'lucide-react';
import { Fragment } from 'react';
import { FormattedMessage } from 'react-intl';
import { useHistory } from 'react-router-dom';

import logo from '../../../src/assets/icons/shinkai-min.svg';
import { srcUrlResolver } from '../../helpers/src-url-resolver';
import { useAuth } from '../../store/auth/auth';
import { Button } from '../ui/button';
import { ScrollArea } from '../ui/scroll-area';
import { Separator } from '../ui/separator';

Expand All @@ -29,19 +35,38 @@ export const Inboxes = () => {

return (
<div className="h-full flex flex-col space-y-3 justify-between overflow-hidden">
<ScrollArea>
{inboxIds?.map((inboxId) => (
<div key={inboxId}>
<div
className="text-ellipsis overflow-hidden whitespace-nowrap"
onClick={() => navigateToInbox(inboxId)}
>
{inboxId}
</div>
<Separator className="my-2" />
{!inboxIds?.length ? (
<div className="grow flex flex-col space-y-3 items-center justify-center">
<div className="grid place-content-center">
<img
alt="shinkai logo"
className="animate-spin-slow h-20 w-20"
data-cy="shinkai-logo"
src={srcUrlResolver(logo)}
/>
</div>
))}
</ScrollArea>
<p className="text-lg">
<FormattedMessage id="ask-to-shinkai-ai" />
</p>
<p className="text-sm text-center">
<FormattedMessage id="ask-to-shinkai-ai-example" />
</p>

<Button className="w-full" onClick={() => history.push('/agents/add')}>
<Bot className="w-4 h-4"/>
<FormattedMessage id="add-agent" />
</Button>
</div>
) : (
<ScrollArea className="[&>div>div]:!block">
{inboxIds?.map((inboxId) => (
<Fragment key={inboxId}>
<Button className="text-ellipsis overflow-hidden whitespace-nowrap" onClick={() => navigateToInbox(inboxId)} variant="link">{decodeURIComponent(inboxId)}</Button>
<Separator className="my-2" />
</Fragment>
))}
</ScrollArea>
)}
</div>
);
};
4 changes: 2 additions & 2 deletions apps/shinkai-visor/src/components/nav/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ export default function NavBar() {
history.replace('/inboxes');
break;
case MenuOption.CreateInbox:
history.replace('/inboxes/create');
history.replace('/inboxes/create-inbox');
break;
case MenuOption.CreateJob:
history.replace('/jobs/create');
history.replace('/inboxes/create-job');
break;
case MenuOption.Agents:
history.replace('/agents');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ export const PopupRouting = () => {
<WithNav>
<Route path="/inboxes">
<Switch>
<Route path="/inboxes/create">
<Route path="/inboxes/create-inbox">
<CreateInbox></CreateInbox>
</Route>
<Route path="/inboxes/create-job">
<CreateJob></CreateJob>
</Route>
<Route path="/inboxes/:inboxId">
<Inbox></Inbox>
</Route>
Expand All @@ -80,14 +83,6 @@ export const PopupRouting = () => {
</Route>
</Switch>
</Route>

<Route path="/jobs">
<Switch>
<Route path="/jobs/create">
<CreateJob></CreateJob>
</Route>
</Switch>
</Route>
</WithNav>
<Route path="*">
<NotFound></NotFound>
Expand Down
Loading
Loading