feat: component viewer (#781)
* wip: component viewer * feat: get component status from component viewer * fix: remove unused property * chore(deps): snjs 2.29.0 * fix: import location
This commit is contained in:
115
app/assets/javascripts/preferences/panes/CloudLink.tsx
Normal file
115
app/assets/javascripts/preferences/panes/CloudLink.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import { FunctionComponent } from 'preact';
|
||||
import {
|
||||
Title,
|
||||
Subtitle,
|
||||
Text,
|
||||
LinkButton,
|
||||
PreferencesGroup,
|
||||
PreferencesPane,
|
||||
PreferencesSegment,
|
||||
} from '../components';
|
||||
|
||||
export const CloudLink: FunctionComponent = () => (
|
||||
<PreferencesPane>
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<Title>Frequently asked questions</Title>
|
||||
<div className="h-2 w-full" />
|
||||
<Subtitle>Who can read my private notes?</Subtitle>
|
||||
<Text>
|
||||
Quite simply: no one but you. Not us, not your ISP, not a hacker, and
|
||||
not a government agency. As long as you keep your password safe, and
|
||||
your password is reasonably strong, then you are the only person in
|
||||
the world with the ability to decrypt your notes. For more on how we
|
||||
handle your privacy and security, check out our easy to read{' '}
|
||||
<a target="_blank" href="https://standardnotes.com/privacy">
|
||||
Privacy Manifesto.
|
||||
</a>
|
||||
</Text>
|
||||
</PreferencesSegment>
|
||||
<PreferencesSegment>
|
||||
<Subtitle>Can I collaborate with others on a note?</Subtitle>
|
||||
<Text>
|
||||
Because of our encrypted architecture, Standard Notes does not
|
||||
currently provide a real-time collaboration solution. Multiple users
|
||||
can share the same account however, but editing at the same time may
|
||||
result in sync conflicts, which may result in the duplication of
|
||||
notes.
|
||||
</Text>
|
||||
</PreferencesSegment>
|
||||
<PreferencesSegment>
|
||||
<Subtitle>Can I use Standard Notes totally offline?</Subtitle>
|
||||
<Text>
|
||||
Standard Notes can be used totally offline without an account, and
|
||||
without an internet connection. You can find{' '}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://standardnotes.com/help/59/can-i-use-standard-notes-totally-offline"
|
||||
>
|
||||
more details here.
|
||||
</a>
|
||||
</Text>
|
||||
</PreferencesSegment>
|
||||
<PreferencesSegment>
|
||||
<Subtitle>Can’t find your question here?</Subtitle>
|
||||
<LinkButton
|
||||
className="mt-3"
|
||||
label="Open FAQ"
|
||||
link="https://standardnotes.com/help"
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<Title>Community forum</Title>
|
||||
<Text>
|
||||
If you have an issue, found a bug or want to suggest a feature, you
|
||||
can browse or post to the forum. It’s recommended for non-account
|
||||
related issues. Please read our{' '}
|
||||
<a target="_blank" href="https://standardnotes.com/longevity/">
|
||||
Longevity statement
|
||||
</a>{' '}
|
||||
before advocating for a feature request.
|
||||
</Text>
|
||||
<LinkButton
|
||||
className="mt-3"
|
||||
label="Go to the forum"
|
||||
link="https://forum.standardnotes.org/"
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<Title>Community groups</Title>
|
||||
<Text>
|
||||
Want to meet other passionate note-takers and privacy enthusiasts?
|
||||
Want to share your feedback with us? Join the Standard Notes community
|
||||
groups for discussions on security, themes, editors and more.
|
||||
</Text>
|
||||
<LinkButton
|
||||
className="mt-3"
|
||||
link="https://standardnotes.com/slack"
|
||||
label="Join our Slack"
|
||||
/>
|
||||
<LinkButton
|
||||
className="mt-3"
|
||||
link="https://standardnotes.com/discord"
|
||||
label="Join our Discord"
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<Title>Account related issue?</Title>
|
||||
<Text>
|
||||
Send an email to help@standardnotes.com and we’ll sort it out.
|
||||
</Text>
|
||||
<LinkButton
|
||||
className="mt-3"
|
||||
link="mailto: help@standardnotes.com"
|
||||
label="Email us"
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
</PreferencesPane>
|
||||
);
|
||||
@@ -1,12 +1,13 @@
|
||||
import { PreferencesGroup, PreferencesSegment } from "@/preferences/components";
|
||||
import { WebApplication } from "@/ui_models/application";
|
||||
import { SNComponent } from "@standardnotes/snjs/dist/@types";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { FunctionComponent } from "preact";
|
||||
import { ExtensionItem } from "./extensions-segments";
|
||||
import { PreferencesGroup, PreferencesSegment } from '@/preferences/components';
|
||||
import { WebApplication } from '@/ui_models/application';
|
||||
import { ComponentViewer, SNComponent } from '@standardnotes/snjs/dist/@types';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { FunctionComponent } from 'preact';
|
||||
import { ExtensionItem } from './extensions-segments';
|
||||
import { ComponentView } from '@/components/ComponentView';
|
||||
import { AppState } from '@/ui_models/app_state';
|
||||
import { PreferencesMenu } from '@/preferences/PreferencesMenu';
|
||||
import { useEffect, useState } from 'preact/hooks';
|
||||
|
||||
interface IProps {
|
||||
application: WebApplication;
|
||||
@@ -17,7 +18,17 @@ interface IProps {
|
||||
|
||||
export const ExtensionPane: FunctionComponent<IProps> = observer(
|
||||
({ extension, application, appState, preferencesMenu }) => {
|
||||
const latestVersion = preferencesMenu.extensionsLatestVersions.getVersion(extension);
|
||||
const [componentViewer] = useState<ComponentViewer>(
|
||||
application.componentManager.createComponentViewer(extension)
|
||||
);
|
||||
const latestVersion =
|
||||
preferencesMenu.extensionsLatestVersions.getVersion(extension);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
application.componentManager.destroyComponentViewer(componentViewer);
|
||||
};
|
||||
}, [application, componentViewer]);
|
||||
|
||||
return (
|
||||
<div className="preferences-extension-pane color-foreground flex-grow flex flex-row overflow-y-auto min-h-0">
|
||||
@@ -28,15 +39,18 @@ export const ExtensionPane: FunctionComponent<IProps> = observer(
|
||||
application={application}
|
||||
extension={extension}
|
||||
first={false}
|
||||
uninstall={() => application.deleteItem(extension).then(() => preferencesMenu.loadExtensionsPanes())}
|
||||
toggleActivate={() => application.toggleComponent(extension).then(() => preferencesMenu.loadExtensionsPanes())}
|
||||
uninstall={() =>
|
||||
application
|
||||
.deleteItem(extension)
|
||||
.then(() => preferencesMenu.loadExtensionsPanes())
|
||||
}
|
||||
latestVersion={latestVersion}
|
||||
/>
|
||||
<PreferencesSegment>
|
||||
<ComponentView
|
||||
application={application}
|
||||
appState={appState}
|
||||
componentUuid={extension.uuid}
|
||||
componentViewer={componentViewer}
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
@@ -44,4 +58,5 @@ export const ExtensionPane: FunctionComponent<IProps> = observer(
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -77,11 +77,6 @@ export const Extensions: FunctionComponent<{
|
||||
setExtensions(loadExtensions(application));
|
||||
};
|
||||
|
||||
const toggleActivateExtension = (extension: SNComponent) => {
|
||||
application.toggleComponent(extension);
|
||||
setExtensions(loadExtensions(application));
|
||||
};
|
||||
|
||||
const visibleExtensions = extensions.filter((extension) => {
|
||||
return (
|
||||
extension.package_info != undefined &&
|
||||
@@ -105,7 +100,6 @@ export const Extensions: FunctionComponent<{
|
||||
latestVersion={extensionsLatestVersions.getVersion(extension)}
|
||||
first={i === 0}
|
||||
uninstall={uninstallExtension}
|
||||
toggleActivate={toggleActivateExtension}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -17,8 +17,9 @@ const DisclosureIconButton: FunctionComponent<{
|
||||
<DisclosureButton
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
className={`no-border cursor-pointer bg-transparent hover:brightness-130 p-0 ${className ?? ''
|
||||
}`}
|
||||
className={`no-border cursor-pointer bg-transparent hover:brightness-130 p-0 ${
|
||||
className ?? ''
|
||||
}`}
|
||||
>
|
||||
<Icon type={icon} />
|
||||
</DisclosureButton>
|
||||
|
||||
Reference in New Issue
Block a user