Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"prebuild": "yarn clean",
"build": "webpack --config web.webpack.prod.js && yarn tsc",
"lint": "eslint src/javascripts",
"format": "prettier --write src/javascripts",
"tsc": "tsc --project tsconfig.json",
"test": "jest --config jest.config.js --coverage",
"upgrade:snjs": "ncu -u '@standardnotes/*'"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { FunctionComponent } from 'react'
import OfflineSubscription from '@/Components/Preferences/Panes/Account/OfflineSubscription'
import OfflineSubscription from '@/Components/Preferences/Panes/General/Advanced/OfflineSubscription'
import { WebApplication } from '@/Application/Application'
import { observer } from 'mobx-react-lite'
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import Extensions from '@/Components/Preferences/Panes/Extensions/Extensions'
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
import PackagesPreferencesSection from '@/Components/Preferences/Panes/General/Advanced/Packages/Section'
import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider'
import AccordionItem from '@/Components/Shared/AccordionItem'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import PreferencesGroup from '../../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../../PreferencesComponents/PreferencesSegment'

type Props = {
application: WebApplication
viewControllerManager: ViewControllerManager
extensionsLatestVersions: ExtensionsLatestVersions
extensionsLatestVersions: PackageProvider
}

const Advanced: FunctionComponent<Props> = ({ application, viewControllerManager, extensionsLatestVersions }) => {
return (
<PreferencesGroup>
<PreferencesSegment>
<AccordionItem title={'Advanced Settings'}>
<AccordionItem title={'Advanced Options'}>
<div className="flex flex-row items-center">
<div className="flex flex-grow flex-col">
<OfflineSubscription application={application} viewControllerManager={viewControllerManager} />
<Extensions
<PackagesPreferencesSection
className={'mt-3'}
application={application}
extensionsLatestVersions={extensionsLatestVersions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { DisplayStringForContentType } from '@standardnotes/snjs'
import Button from '@/Components/Button/Button'
import { Fragment, FunctionComponent } from 'react'
import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import { AnyExtension } from './AnyExtension'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import { AnyPackageType } from './Types/AnyPackageType'
import PreferencesSegment from '../../../../PreferencesComponents/PreferencesSegment'

const ConfirmCustomExtension: FunctionComponent<{
component: AnyExtension
const ConfirmCustomPackage: FunctionComponent<{
component: AnyPackageType
callback: (confirmed: boolean) => void
}> = ({ component, callback }) => {
const fields = [
Expand Down Expand Up @@ -66,4 +66,4 @@ const ConfirmCustomExtension: FunctionComponent<{
)
}

export default ConfirmCustomExtension
export default ConfirmCustomPackage
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { ComponentMutator, SNComponent } from '@standardnotes/snjs'
import { SubtitleLight } from '@/Components/Preferences/PreferencesComponents/Content'
import Switch from '@/Components/Switch/Switch'
import Button from '@/Components/Button/Button'
import ExtensionInfoCell from './ExtensionInfoCell'
import { ExtensionItemProps } from './ExtensionItemProps'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import PackageEntrySubInfo from './PackageEntrySubInfo'
import PreferencesSegment from '../../../../PreferencesComponents/PreferencesSegment'
import { WebApplication } from '@/Application/Application'
import { AnyPackageType } from './Types/AnyPackageType'

const UseHosted: FunctionComponent<{
offlineOnly: boolean
Expand All @@ -17,7 +18,16 @@ const UseHosted: FunctionComponent<{
</div>
)

const ExtensionItem: FunctionComponent<ExtensionItemProps> = ({ application, extension, uninstall }) => {
interface PackageEntryProps {
application: WebApplication
extension: AnyPackageType
first: boolean
latestVersion: string | undefined
uninstall: (extension: AnyPackageType) => void
toggleActivate?: (extension: AnyPackageType) => void
}

const PackageEntry: FunctionComponent<PackageEntryProps> = ({ application, extension, uninstall }) => {
const [offlineOnly, setOfflineOnly] = useState(extension instanceof SNComponent ? extension.offlineOnly : false)
const [extensionName, setExtensionName] = useState(extension.displayName)

Expand Down Expand Up @@ -56,7 +66,7 @@ const ExtensionItem: FunctionComponent<ExtensionItemProps> = ({ application, ext

return (
<PreferencesSegment classes={'mb-5'}>
<ExtensionInfoCell isThirdParty={isThirdParty} extensionName={extensionName} changeName={changeExtensionName} />
<PackageEntrySubInfo isThirdParty={isThirdParty} extensionName={extensionName} changeName={changeExtensionName} />

<div className="my-1" />

Expand All @@ -71,4 +81,4 @@ const ExtensionItem: FunctionComponent<ExtensionItemProps> = ({ application, ext
)
}

export default ExtensionItem
export default PackageEntry
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type Props = {
isThirdParty: boolean
}

const ExtensionInfoCell: FunctionComponent<Props> = ({ extensionName, changeName, isThirdParty }) => {
const PackageEntrySubInfo: FunctionComponent<Props> = ({ extensionName, changeName, isThirdParty }) => {
const [isRenaming, setIsRenaming] = useState(false)
const [newExtensionName, setNewExtensionName] = useState<string>(extensionName)

Expand Down Expand Up @@ -73,4 +73,4 @@ const ExtensionInfoCell: FunctionComponent<Props> = ({ extensionName, changeName
)
}

export default ExtensionInfoCell
export default PackageEntrySubInfo
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { WebApplication } from '@/Application/Application'
import { ClientDisplayableError, FeatureDescription } from '@standardnotes/snjs'
import { makeAutoObservable, observable } from 'mobx'
import { AnyExtension } from './AnyExtension'
import { AnyPackageType } from '../Types/AnyPackageType'
import { ComponentChecksumsType } from '@standardnotes/components-meta'
import RawComponentChecksumsFile from '@standardnotes/components-meta/dist/zips/checksums.json'
const ComponentChecksums = RawComponentChecksumsFile as ComponentChecksumsType

export class ExtensionsLatestVersions {
static async load(application: WebApplication): Promise<ExtensionsLatestVersions | undefined> {
export class PackageProvider {
static async load(application: WebApplication): Promise<PackageProvider | undefined> {
const response = await application.getAvailableSubscriptions()

if (response instanceof ClientDisplayableError) {
Expand All @@ -18,16 +18,16 @@ export class ExtensionsLatestVersions {
collectFeatures(response.PLUS_PLAN?.features as FeatureDescription[], versionMap)
collectFeatures(response.PRO_PLAN?.features as FeatureDescription[], versionMap)

return new ExtensionsLatestVersions(versionMap)
return new PackageProvider(versionMap)
}

constructor(private readonly latestVersionsMap: Map<string, string>) {
makeAutoObservable<ExtensionsLatestVersions, 'latestVersionsMap'>(this, {
makeAutoObservable<PackageProvider, 'latestVersionsMap'>(this, {
latestVersionsMap: observable.ref,
})
}

getVersion(extension: AnyExtension): string | undefined {
getVersion(extension: AnyPackageType): string | undefined {
return this.latestVersionsMap.get(extension.package_info.identifier)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,34 @@ import Button from '@/Components/Button/Button'
import DecoratedInput from '@/Components/Input/DecoratedInput'
import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useEffect, useRef, useState } from 'react'
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import { observer } from 'mobx-react-lite'
import { ExtensionsLatestVersions } from './ExtensionsLatestVersions'
import ExtensionItem from './ExtensionItem'
import ConfirmCustomExtension from './ConfirmCustomExtension'
import { AnyExtension } from './AnyExtension'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import { PackageProvider } from './Provider/PackageProvider'
import PackageEntry from './PackageEntry'
import ConfirmCustomPackage from './ConfirmCustomPackage'
import { AnyPackageType } from './Types/AnyPackageType'
import PreferencesSegment from '../../../../PreferencesComponents/PreferencesSegment'

const loadExtensions = (application: WebApplication) =>
application.items.getItems([ContentType.ActionsExtension, ContentType.Component, ContentType.Theme]) as AnyExtension[]
application.items.getItems([
ContentType.ActionsExtension,
ContentType.Component,
ContentType.Theme,
]) as AnyPackageType[]

type Props = {
application: WebApplication
extensionsLatestVersions: ExtensionsLatestVersions
extensionsLatestVersions: PackageProvider
className?: string
}

const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVersions, className = '' }) => {
const PackagesPreferencesSection: FunctionComponent<Props> = ({
application,
extensionsLatestVersions,
className = '',
}) => {
const [customUrl, setCustomUrl] = useState('')
const [confirmableExtension, setConfirmableExtension] = useState<AnyExtension | undefined>(undefined)
const [confirmableExtension, setConfirmableExtension] = useState<AnyPackageType | undefined>(undefined)
const [extensions, setExtensions] = useState(loadExtensions(application))

const confirmableEnd = useRef<HTMLDivElement>(null)
Expand All @@ -33,7 +41,7 @@ const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVer
}
}, [confirmableExtension, confirmableEnd])

const uninstallExtension = async (extension: AnyExtension) => {
const uninstallExtension = async (extension: AnyPackageType) => {
application.alertService
.confirm(
'Are you sure you want to uninstall this extension? Note that extensions managed by your subscription will automatically be re-installed on application restart.',
Expand Down Expand Up @@ -69,7 +77,7 @@ const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVer
}

const confirmExtension = async () => {
await application.mutator.insertItem(confirmableExtension as AnyExtension)
await application.mutator.insertItem(confirmableExtension as AnyPackageType)
application.sync.sync().catch(console.error)
setExtensions(loadExtensions(application))
}
Expand All @@ -95,7 +103,7 @@ const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVer
{visibleExtensions
.sort((e1, e2) => e1.displayName?.toLowerCase().localeCompare(e2.displayName?.toLowerCase()))
.map((extension, i) => (
<ExtensionItem
<PackageEntry
key={extension.uuid}
application={application}
extension={extension}
Expand All @@ -110,20 +118,28 @@ const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVer
<div>
{!confirmableExtension && (
<PreferencesSegment>
<Title>Install Custom Extension</Title>
<DecoratedInput
placeholder={'Enter Extension URL'}
value={customUrl}
onChange={(value) => {
setCustomUrl(value)
}}
<Subtitle>Install External Package</Subtitle>
<div className={'mt-2'}>
<DecoratedInput
placeholder={'Enter Package URL'}
value={customUrl}
onChange={(value) => {
setCustomUrl(value)
}}
/>
</div>
<Button
disabled={customUrl.length === 0}
className="mt-3 min-w-20"
primary
label="Install"
onClick={() => submitExtensionUrl(customUrl)}
/>
<Button className="mt-3 min-w-20" label="Install" onClick={() => submitExtensionUrl(customUrl)} />
</PreferencesSegment>
)}
{confirmableExtension && (
<PreferencesSegment>
<ConfirmCustomExtension component={confirmableExtension} callback={handleConfirmExtensionSubmit} />
<ConfirmCustomPackage component={confirmableExtension} callback={handleConfirmExtensionSubmit} />
<div ref={confirmableEnd} />
</PreferencesSegment>
)}
Expand All @@ -132,4 +148,4 @@ const Extensions: FunctionComponent<Props> = ({ application, extensionsLatestVer
)
}

export default observer(Extensions)
export default observer(PackagesPreferencesSection)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { SNActionsExtension, SNComponent, SNTheme } from '@standardnotes/snjs'

export type AnyExtension = SNComponent | SNTheme | SNActionsExtension
export type AnyPackageType = SNComponent | SNTheme | SNActionsExtension
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { WebApplication } from '@/Application/Application'
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FunctionComponent } from 'react'
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider'
import { observer } from 'mobx-react-lite'
import Tools from './Tools'
import Defaults from './Defaults'
import LabsPane from './Labs/Labs'
import Advanced from '@/Components/Preferences/Panes/Account/Advanced'
import Advanced from '@/Components/Preferences/Panes/General/Advanced/AdvancedSection'
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'

type Props = {
viewControllerManager: ViewControllerManager
application: WebApplication
extensionsLatestVersions: ExtensionsLatestVersions
extensionsLatestVersions: PackageProvider
}

const General: FunctionComponent<Props> = ({ viewControllerManager, application, extensionsLatestVersions }) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { WebApplication } from '@/Application/Application'
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FunctionComponent } from 'react'
import TwoFactorAuthWrapper from '../TwoFactorAuth/TwoFactorAuthWrapper'
import { MfaProps } from '../TwoFactorAuth/MfaProps'
import TwoFactorAuthWrapper from './TwoFactorAuth/TwoFactorAuthWrapper'
import { MfaProps } from './TwoFactorAuth/MfaProps'
import Encryption from './Encryption'
import PasscodeLock from './PasscodeLock'
import Privacy from './Privacy'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { action, makeAutoObservable, observable } from 'mobx'
import { IconType } from '@standardnotes/snjs'
import { WebApplication } from '@/Application/Application'
import { ExtensionsLatestVersions } from './Panes/Extensions/ExtensionsLatestVersions'
import { PackageProvider } from './Panes/General/Advanced/Packages/Provider/PackageProvider'
import { securityPrefsHasBubble } from './Panes/Security/securityPrefsHasBubble'

const PREFERENCE_IDS = [
Expand Down Expand Up @@ -59,7 +59,7 @@ const READY_PREFERENCES_MENU_ITEMS: PreferencesMenuItem[] = [
export class PreferencesMenu {
private _selectedPane: PreferenceId = 'account'
private _menu: PreferencesMenuItem[]
private _extensionLatestVersions: ExtensionsLatestVersions = new ExtensionsLatestVersions(new Map())
private _extensionLatestVersions: PackageProvider = new PackageProvider(new Map())

constructor(private application: WebApplication, private readonly _enableUnfinishedFeatures: boolean) {
this._menu = this._enableUnfinishedFeatures ? PREFERENCES_MENU_ITEMS : READY_PREFERENCES_MENU_ITEMS
Expand All @@ -79,7 +79,7 @@ export class PreferencesMenu {
}

private loadLatestVersions(): void {
ExtensionsLatestVersions.load(this.application)
PackageProvider.load(this.application)
.then((versions) => {
if (versions) {
this._extensionLatestVersions = versions
Expand All @@ -88,7 +88,7 @@ export class PreferencesMenu {
.catch(console.error)
}

get extensionsLatestVersions(): ExtensionsLatestVersions {
get extensionsLatestVersions(): PackageProvider {
return this._extensionLatestVersions
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WebApplication } from '@/Application/Application'
import { MfaProps } from './Panes/TwoFactorAuth/MfaProps'
import { MfaProps } from './Panes/Security/TwoFactorAuth/MfaProps'
import { ViewControllerManager } from '@/Services/ViewControllerManager'

export interface PreferencesProps extends MfaProps {
Expand Down