mirror of
https://github.com/standardnotes/web.git
synced 2024-10-05 19:58:26 +03:00
feat: toast package (#1073)
This commit is contained in:
parent
de94fb69cf
commit
6d0b6e9018
3
babel.config.js
Normal file
3
babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
babelrcRoots: ['.', './packages/*'],
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
"../../node_modules/@standardnotes/config/src/.eslintrc"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"ignorePatterns": ["test", "scripts", ".eslintrc", "tsconfig.json", "node_modules"],
|
||||
"ignorePatterns": ["test", "scripts", ".eslintrc", "tsconfig.json", "node_modules", "*.webpack.*.js"],
|
||||
"rules": {
|
||||
/** Style */
|
||||
"quotes": ["error", "single", { "avoidEscape": true }],
|
||||
|
2
packages/toast/.eslintignore
Normal file
2
packages/toast/.eslintignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
3
packages/toast/.eslintrc
Normal file
3
packages/toast/.eslintrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": ["../../node_modules/@standardnotes/config/src/.eslintrc"]
|
||||
}
|
1
packages/toast/.gitignore
vendored
Normal file
1
packages/toast/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
dist
|
3
packages/toast/linter.tsconfig.json
Normal file
3
packages/toast/linter.tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../node_modules/@standardnotes/config/src/linter.tsconfig.json"
|
||||
}
|
32
packages/toast/package.json
Normal file
32
packages/toast/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@standardnotes/toast",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn run tsc",
|
||||
"clean": "rm -fr dist",
|
||||
"prestart": "yarn clean",
|
||||
"start": "tsc -p tsconfig.json --watch",
|
||||
"prebuild": "yarn clean",
|
||||
"lint": "eslint ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nanostores/react": "^0.2.0",
|
||||
"@standardnotes/config": "^2.4.3",
|
||||
"@standardnotes/icons": "^1.1.7",
|
||||
"nanoid": "^3.3.4",
|
||||
"nanostores": "^0.5.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.18.0",
|
||||
"@babel/preset-react": "^7.17.12",
|
||||
"@babel/preset-typescript": "^7.17.12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "17"
|
||||
}
|
||||
}
|
133
packages/toast/src/Toast.tsx
Normal file
133
packages/toast/src/Toast.tsx
Normal file
@ -0,0 +1,133 @@
|
||||
import type { Toast as ToastPropType } from './types'
|
||||
import { CheckCircleFilledIcon, ClearCircleFilledIcon } from '@standardnotes/icons'
|
||||
import { dismissToast } from './toastStore'
|
||||
import { ToastType } from './enums'
|
||||
import { ForwardedRef, forwardRef, RefObject, useEffect } from 'react'
|
||||
|
||||
const prefersReducedMotion = () => {
|
||||
const mediaQuery = matchMedia('(prefers-reduced-motion: reduce)')
|
||||
return mediaQuery.matches
|
||||
}
|
||||
|
||||
const colorForToastType = (type: ToastType) => {
|
||||
switch (type) {
|
||||
case ToastType.Success:
|
||||
return 'color-success'
|
||||
case ToastType.Error:
|
||||
return 'color-danger'
|
||||
default:
|
||||
return 'color-info'
|
||||
}
|
||||
}
|
||||
|
||||
const iconForToastType = (type: ToastType) => {
|
||||
switch (type) {
|
||||
case ToastType.Success:
|
||||
return <CheckCircleFilledIcon className={colorForToastType(type)} />
|
||||
case ToastType.Error:
|
||||
return <ClearCircleFilledIcon className={colorForToastType(type)} />
|
||||
case ToastType.Progress:
|
||||
case ToastType.Loading:
|
||||
return <div className="sk-spinner w-4 h-4 spinner-info" />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
type Props = {
|
||||
toast: ToastPropType
|
||||
index: number
|
||||
}
|
||||
|
||||
export const Toast = forwardRef(({ toast, index }: Props, ref: ForwardedRef<HTMLDivElement>) => {
|
||||
const icon = iconForToastType(toast.type)
|
||||
const hasActions = toast.actions && toast.actions.length > 0
|
||||
const hasProgress = toast.type === ToastType.Progress && toast.progress !== undefined && toast.progress > -1
|
||||
|
||||
const shouldReduceMotion = prefersReducedMotion()
|
||||
const enterAnimation = shouldReduceMotion ? 'fade-in-animation' : 'slide-in-right-animation'
|
||||
const exitAnimation = shouldReduceMotion ? 'fade-out-animation' : 'slide-out-left-animation'
|
||||
const currentAnimation = toast.dismissed ? exitAnimation : enterAnimation
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref) {
|
||||
return
|
||||
}
|
||||
|
||||
const element = (ref as RefObject<HTMLDivElement>).current
|
||||
|
||||
if (element && toast.dismissed) {
|
||||
const { scrollHeight, style } = element
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
style.minHeight = 'initial'
|
||||
style.height = scrollHeight + 'px'
|
||||
style.transition = 'all 200ms'
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
style.height = '0'
|
||||
style.padding = '0'
|
||||
style.margin = '0'
|
||||
})
|
||||
})
|
||||
}
|
||||
}, [ref, toast.dismissed])
|
||||
|
||||
return (
|
||||
<div
|
||||
data-index={index}
|
||||
role="status"
|
||||
className={`flex flex-col bg-passive-5 rounded opacity-0 animation-fill-forwards select-none min-w-max relative mt-3 ${currentAnimation}`}
|
||||
style={{
|
||||
boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.16)',
|
||||
transition: shouldReduceMotion ? undefined : 'all 0.2s ease',
|
||||
animationDelay: !toast.dismissed ? '50ms' : undefined,
|
||||
}}
|
||||
onClick={() => {
|
||||
if (!hasActions && toast.type !== ToastType.Loading && toast.type !== ToastType.Progress) {
|
||||
dismissToast(toast.id)
|
||||
}
|
||||
}}
|
||||
ref={ref}
|
||||
>
|
||||
<div className={`flex items-center w-full ${hasActions ? 'p-2 pl-3' : hasProgress ? 'px-3 py-2.5' : 'p-3'}`}>
|
||||
{icon ? <div className="flex flex-shrink-0 items-center justify-center sn-icon mr-2">{icon}</div> : null}
|
||||
<div className="text-sm">{toast.message}</div>
|
||||
{hasActions && (
|
||||
<div className="ml-4">
|
||||
{toast.actions?.map((action, index) => (
|
||||
<button
|
||||
style={{
|
||||
paddingLeft: '0.45rem',
|
||||
paddingRight: '0.45rem',
|
||||
}}
|
||||
className={`py-1 border-0 bg-transparent cursor-pointer font-semibold text-sm hover:bg-passive-3 rounded ${colorForToastType(
|
||||
toast.type,
|
||||
)} ${index !== 0 ? 'ml-2' : ''}`}
|
||||
onClick={() => {
|
||||
action.handler(toast.id)
|
||||
}}
|
||||
key={index}
|
||||
>
|
||||
{action.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{hasProgress && (
|
||||
<div className="toast-progress-bar">
|
||||
<div
|
||||
className="toast-progress-bar__value"
|
||||
role="progressbar"
|
||||
style={{
|
||||
width: `${toast.progress}%`,
|
||||
...(toast.progress === 100 ? { borderTopRightRadius: 0 } : {}),
|
||||
}}
|
||||
aria-valuenow={toast.progress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
20
packages/toast/src/ToastContainer.tsx
Normal file
20
packages/toast/src/ToastContainer.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { FunctionComponent } from 'react'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { toastStore } from './toastStore'
|
||||
import { ToastTimer } from './ToastTimer'
|
||||
|
||||
export const ToastContainer: FunctionComponent = () => {
|
||||
const toasts = useStore(toastStore)
|
||||
|
||||
if (!toasts.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-end fixed z-index-toast bottom-6 right-6">
|
||||
{toasts.map((toast, index) => (
|
||||
<ToastTimer toast={toast} index={index} key={toast.id} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
115
packages/toast/src/ToastTimer.tsx
Normal file
115
packages/toast/src/ToastTimer.tsx
Normal file
@ -0,0 +1,115 @@
|
||||
import { useCallback, useEffect, useRef, FunctionComponent } from 'react'
|
||||
import { Toast } from './Toast'
|
||||
import { Toast as ToastPropType } from './types'
|
||||
import { ToastType } from './enums'
|
||||
import { dismissToast } from './toastStore'
|
||||
|
||||
type Props = {
|
||||
toast: ToastPropType
|
||||
index: number
|
||||
}
|
||||
|
||||
const getDefaultForAutoClose = (hasActions: boolean, type: ToastType) => {
|
||||
return !hasActions && ![ToastType.Loading, ToastType.Progress].includes(type)
|
||||
}
|
||||
|
||||
const getDefaultToastDuration = (type: ToastType) => (type === ToastType.Error ? 8000 : 4000)
|
||||
|
||||
export const ToastTimer: FunctionComponent<Props> = ({ toast, index }) => {
|
||||
const toastElementRef = useRef<HTMLDivElement>(null)
|
||||
const toastTimerIdRef = useRef<number>()
|
||||
|
||||
const hasActions = Boolean(toast.actions?.length)
|
||||
const shouldAutoClose = toast.autoClose ?? getDefaultForAutoClose(hasActions, toast.type)
|
||||
const duration = toast.duration ?? getDefaultToastDuration(toast.type)
|
||||
|
||||
const startTimeRef = useRef(duration)
|
||||
const remainingTimeRef = useRef(duration)
|
||||
|
||||
const dismissToastOnEnd = useCallback(() => {
|
||||
dismissToast(toast.id)
|
||||
}, [toast.id])
|
||||
|
||||
const clearTimer = useCallback(() => {
|
||||
if (toastTimerIdRef.current) {
|
||||
clearTimeout(toastTimerIdRef.current)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const pauseTimer = useCallback(() => {
|
||||
clearTimer()
|
||||
remainingTimeRef.current -= Date.now() - startTimeRef.current
|
||||
}, [clearTimer])
|
||||
|
||||
const resumeTimer = useCallback(() => {
|
||||
startTimeRef.current = Date.now()
|
||||
clearTimer()
|
||||
toastTimerIdRef.current = window.setTimeout(dismissToastOnEnd, remainingTimeRef.current)
|
||||
}, [clearTimer, dismissToastOnEnd])
|
||||
|
||||
const handleMouseEnter = useCallback(() => {
|
||||
pauseTimer()
|
||||
}, [pauseTimer])
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
resumeTimer()
|
||||
}, [resumeTimer])
|
||||
|
||||
const handlePageVisibility = useCallback(() => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
pauseTimer()
|
||||
} else {
|
||||
resumeTimer()
|
||||
}
|
||||
}, [pauseTimer, resumeTimer])
|
||||
|
||||
const handlePageFocus = useCallback(() => {
|
||||
resumeTimer()
|
||||
}, [resumeTimer])
|
||||
|
||||
const handlePageBlur = useCallback(() => {
|
||||
pauseTimer()
|
||||
}, [pauseTimer])
|
||||
|
||||
useEffect(() => {
|
||||
clearTimer()
|
||||
|
||||
if (shouldAutoClose) {
|
||||
resumeTimer()
|
||||
}
|
||||
|
||||
const toastElement = toastElementRef.current
|
||||
if (toastElement) {
|
||||
toastElement.addEventListener('mouseenter', handleMouseEnter)
|
||||
toastElement.addEventListener('mouseleave', handleMouseLeave)
|
||||
}
|
||||
document.addEventListener('visibilitychange', handlePageVisibility)
|
||||
window.addEventListener('focus', handlePageFocus)
|
||||
window.addEventListener('blur', handlePageBlur)
|
||||
|
||||
return () => {
|
||||
clearTimer()
|
||||
if (toastElement) {
|
||||
toastElement.removeEventListener('mouseenter', handleMouseEnter)
|
||||
toastElement.removeEventListener('mouseleave', handleMouseLeave)
|
||||
}
|
||||
document.removeEventListener('visibilitychange', handlePageVisibility)
|
||||
window.removeEventListener('focus', handlePageFocus)
|
||||
window.removeEventListener('blur', handlePageBlur)
|
||||
}
|
||||
}, [
|
||||
clearTimer,
|
||||
dismissToastOnEnd,
|
||||
duration,
|
||||
handleMouseEnter,
|
||||
handleMouseLeave,
|
||||
handlePageBlur,
|
||||
handlePageFocus,
|
||||
handlePageVisibility,
|
||||
resumeTimer,
|
||||
shouldAutoClose,
|
||||
toast.id,
|
||||
])
|
||||
|
||||
return <Toast toast={toast} index={index} ref={toastElementRef} />
|
||||
}
|
35
packages/toast/src/addTimedToast.ts
Normal file
35
packages/toast/src/addTimedToast.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { addToast, dismissToast, updateToast } from './toastStore'
|
||||
import { ToastOptions } from './types'
|
||||
|
||||
type InitialToastOptions = Omit<ToastOptions, 'message'> & {
|
||||
message: (timeRemainingInSeconds: number) => string
|
||||
}
|
||||
|
||||
export const addTimedToast = (
|
||||
initialOptions: InitialToastOptions,
|
||||
callback: () => void,
|
||||
timeInSeconds: number,
|
||||
): [string, number] => {
|
||||
let timeRemainingInSeconds = timeInSeconds
|
||||
|
||||
const intervalId = window.setInterval(() => {
|
||||
timeRemainingInSeconds--
|
||||
if (timeRemainingInSeconds > 0) {
|
||||
updateToast(toastId, {
|
||||
message: initialOptions.message(timeRemainingInSeconds),
|
||||
})
|
||||
} else {
|
||||
dismissToast(toastId)
|
||||
clearInterval(intervalId)
|
||||
callback()
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const toastId = addToast({
|
||||
...initialOptions,
|
||||
message: initialOptions.message(timeRemainingInSeconds),
|
||||
autoClose: false,
|
||||
})
|
||||
|
||||
return [toastId, intervalId]
|
||||
}
|
7
packages/toast/src/enums.ts
Normal file
7
packages/toast/src/enums.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export enum ToastType {
|
||||
Regular = 'regular',
|
||||
Success = 'success',
|
||||
Error = 'error',
|
||||
Loading = 'loading',
|
||||
Progress = 'progress',
|
||||
}
|
5
packages/toast/src/index.ts
Normal file
5
packages/toast/src/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export { ToastContainer } from './ToastContainer'
|
||||
export { addToast, updateToast, dismissToast } from './toastStore'
|
||||
export { ToastType } from './enums'
|
||||
export { addTimedToast } from './addTimedToast'
|
||||
export type { Toast, ToastAction, ToastOptions } from './types'
|
73
packages/toast/src/toastStore.ts
Normal file
73
packages/toast/src/toastStore.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { nanoid } from 'nanoid'
|
||||
import { action, atom, WritableAtom } from 'nanostores'
|
||||
import { Toast, ToastOptions, ToastUpdateOptions } from './types'
|
||||
|
||||
export const toastStore = atom<Toast[]>([])
|
||||
|
||||
export const updateToast = action(
|
||||
toastStore,
|
||||
'updateToast',
|
||||
(store: WritableAtom<Toast[]>, toastId: Toast['id'], options: ToastUpdateOptions) => {
|
||||
const existingToasts = store.get()
|
||||
store.set(
|
||||
existingToasts.map((toast) => {
|
||||
if (toast.id === toastId) {
|
||||
return {
|
||||
...toast,
|
||||
...options,
|
||||
}
|
||||
} else {
|
||||
return toast
|
||||
}
|
||||
}),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
const removeToast = action(toastStore, 'removeToast', (store: WritableAtom<Toast[]>, toastId: Toast['id']) => {
|
||||
const existingToasts = store.get()
|
||||
store.set(existingToasts.filter((toast) => toast.id !== toastId))
|
||||
})
|
||||
|
||||
const DelayBeforeRemovingToast = 175
|
||||
|
||||
export const dismissToast = action(toastStore, 'dismissToast', (store: WritableAtom<Toast[]>, toastId: Toast['id']) => {
|
||||
const existingToasts = store.get()
|
||||
store.set(
|
||||
existingToasts.map((toast) => {
|
||||
if (toast.id === toastId) {
|
||||
return {
|
||||
...toast,
|
||||
dismissed: true,
|
||||
}
|
||||
} else {
|
||||
return toast
|
||||
}
|
||||
}),
|
||||
)
|
||||
setTimeout(() => {
|
||||
removeToast(toastId)
|
||||
}, DelayBeforeRemovingToast)
|
||||
})
|
||||
|
||||
export const addToast = action(toastStore, 'addToast', (store: WritableAtom<Toast[]>, options: ToastOptions) => {
|
||||
const existingToasts = store.get()
|
||||
const isToastIdDuplicate = existingToasts.findIndex((toast) => toast.id === options.id) > -1
|
||||
|
||||
const id = options.id && !isToastIdDuplicate ? options.id : nanoid()
|
||||
|
||||
if (isToastIdDuplicate) {
|
||||
console.warn(`Generated new ID for toast instead of overriding toast of ID "${options.id}".
|
||||
If you want to update an existing toast, use the \`updateToast()\` function instead.`)
|
||||
}
|
||||
|
||||
const toast = {
|
||||
...options,
|
||||
id,
|
||||
dismissed: false,
|
||||
}
|
||||
|
||||
store.set([...existingToasts, toast])
|
||||
|
||||
return id
|
||||
})
|
30
packages/toast/src/types.ts
Normal file
30
packages/toast/src/types.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { ToastType } from './enums'
|
||||
|
||||
export type ToastAction = {
|
||||
label: string
|
||||
handler: (toastId: Toast['id']) => void
|
||||
}
|
||||
|
||||
type CommonToastProperties = {
|
||||
type: ToastType
|
||||
message: string
|
||||
actions?: ToastAction[]
|
||||
progress?: number
|
||||
autoClose?: boolean
|
||||
duration?: number
|
||||
}
|
||||
|
||||
export type Toast = CommonToastProperties & {
|
||||
id: string
|
||||
dismissed: boolean
|
||||
}
|
||||
|
||||
export type ToastOptions = CommonToastProperties & {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export type ToastUpdateOptions = Omit<Partial<ToastOptions>, 'id'>
|
||||
|
||||
export type ToastState = {
|
||||
toasts: Toast[]
|
||||
}
|
13
packages/toast/tsconfig.json
Normal file
13
packages/toast/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../node_modules/@standardnotes/config/src/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"jsx": "react-jsx",
|
||||
"skipLibCheck": true,
|
||||
"module": "es2022"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
"../../node_modules/@standardnotes/config/src/.eslintrc"
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "react", "react-hooks"],
|
||||
"ignorePatterns": [".eslintrc.js", "webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__"],
|
||||
"ignorePatterns": [".eslintrc.js", "*.webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__"],
|
||||
"rules": {
|
||||
"standard/no-callback-literal": 0, // Disable this as we have too many callbacks relying on literals
|
||||
"no-throw-literal": 0,
|
||||
|
@ -1,4 +1,4 @@
|
||||
const pathsToModuleNameMapper = require('ts-jest/utils').pathsToModuleNameMapper
|
||||
const pathsToModuleNameMapper = require('ts-jest').pathsToModuleNameMapper
|
||||
const tsConfig = require('./tsconfig.json')
|
||||
|
||||
const pathsFromTsconfig = tsConfig.compilerOptions.paths
|
||||
@ -12,23 +12,14 @@ module.exports = {
|
||||
prefix: '<rootDir>',
|
||||
}),
|
||||
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
||||
'@standardnotes/toast': 'identity-obj-proxy',
|
||||
},
|
||||
globals: {
|
||||
__WEB_VERSION__: '1.0.0',
|
||||
__DESKTOP__: false,
|
||||
__WEB__: true,
|
||||
self: {}, // fixes error happening on `import { SKAlert } from 'sn-stylekit'`
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.(ts|tsx)?$': 'ts-jest',
|
||||
'\\.svg$': 'svg-jest',
|
||||
},
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 3,
|
||||
functions: 5,
|
||||
lines: 21,
|
||||
statements: 22,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -73,6 +73,7 @@
|
||||
"@standardnotes/sncrypto-web": "1.10.1",
|
||||
"@standardnotes/snjs": "^2.115.6",
|
||||
"@standardnotes/stylekit": "5.29.3",
|
||||
"@standardnotes/toast": "1.0.0",
|
||||
"@zip.js/zip.js": "^2.4.10",
|
||||
"mobx": "^6.5.0",
|
||||
"mobx-react-lite": "^3.3.0",
|
||||
|
@ -18,7 +18,7 @@ import RevisionHistoryModalWrapper from '@/Components/RevisionHistoryModal/Revis
|
||||
import PremiumModalProvider from '@/Hooks/usePremiumModal'
|
||||
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
|
||||
import TagsContextMenuWrapper from '@/Components/Tags/TagContextMenu'
|
||||
import { ToastContainer } from '@standardnotes/stylekit'
|
||||
import { ToastContainer } from '@standardnotes/toast'
|
||||
import FilePreviewModalWrapper from '@/Components/FilePreview/FilePreviewModal'
|
||||
import ContentListView from '@/Components/ContentListView/ContentListView'
|
||||
import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu'
|
||||
|
@ -7,7 +7,7 @@ import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'rea
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
import { FileItem, SNNote } from '@standardnotes/snjs'
|
||||
import { addToast, ToastType } from '@standardnotes/stylekit'
|
||||
import { addToast, ToastType } from '@standardnotes/toast'
|
||||
import { StreamingFileReader } from '@standardnotes/filepicker'
|
||||
import AttachedFilesPopover from './AttachedFilesPopover'
|
||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||
|
@ -8,7 +8,7 @@ import ChangeEditorOption from './ChangeEditorOption'
|
||||
import { BYTES_IN_ONE_MEGABYTE } from '@/Constants/Constants'
|
||||
import ListedActionsOption from './ListedActionsOption'
|
||||
import AddTagOption from './AddTagOption'
|
||||
import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit'
|
||||
import { addToast, dismissToast, ToastType } from '@standardnotes/toast'
|
||||
import { NotesOptionsProps } from './NotesOptionsProps'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
parseFileName,
|
||||
} from '@standardnotes/filepicker'
|
||||
import { ChallengeReason, ClientDisplayableError, ContentType, FileItem, InternalEventBus } from '@standardnotes/snjs'
|
||||
import { addToast, dismissToast, ToastType, updateToast } from '@standardnotes/stylekit'
|
||||
import { addToast, dismissToast, ToastType, updateToast } from '@standardnotes/toast'
|
||||
import { action, makeObservable, observable, reaction } from 'mobx'
|
||||
import { WebApplication } from '../Application/Application'
|
||||
import { AbstractViewController } from './Abstract/AbstractViewController'
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
PayloadEmitSource,
|
||||
LocalStorageDecryptedContextualPayload,
|
||||
} from '@standardnotes/snjs'
|
||||
import { dismissToast, ToastType, addTimedToast } from '@standardnotes/stylekit'
|
||||
import { dismissToast, ToastType, addTimedToast } from '@standardnotes/toast'
|
||||
|
||||
const CachedThemesKey = 'cachedThemes'
|
||||
const TimeBeforeApplyingColorScheme = 5
|
||||
|
@ -22,7 +22,7 @@ module.exports = (env, argv) => {
|
||||
],
|
||||
devServer: {
|
||||
hot: 'only',
|
||||
static: '../../web-server/public',
|
||||
static: '../web-server/public',
|
||||
port,
|
||||
devMiddleware: {
|
||||
writeToDisk: argv.writeToDisk,
|
||||
|
42
yarn.lock
42
yarn.lock
@ -731,7 +731,21 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-react-jsx@^7.17.3":
|
||||
"@babel/plugin-transform-react-display-name@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340"
|
||||
integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-react-jsx-development@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8"
|
||||
integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==
|
||||
dependencies:
|
||||
"@babel/plugin-transform-react-jsx" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-react-jsx@^7.16.7", "@babel/plugin-transform-react-jsx@^7.17.12", "@babel/plugin-transform-react-jsx@^7.17.3":
|
||||
version "7.17.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz#2aa20022709cd6a3f40b45d60603d5f269586dba"
|
||||
integrity sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==
|
||||
@ -742,6 +756,14 @@
|
||||
"@babel/plugin-syntax-jsx" "^7.17.12"
|
||||
"@babel/types" "^7.17.12"
|
||||
|
||||
"@babel/plugin-transform-react-pure-annotations@^7.16.7":
|
||||
version "7.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.0.tgz#ef82c8e310913f3522462c9ac967d395092f1954"
|
||||
integrity sha512-6+0IK6ouvqDn9bmEG7mEyF/pwlJXVj5lwydybpyyH3D0A7Hftk+NCTdYjnLNZksn261xaOV5ksmp20pQEmc2RQ==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.16.7"
|
||||
"@babel/helper-plugin-utils" "^7.17.12"
|
||||
|
||||
"@babel/plugin-transform-regenerator@^7.18.0":
|
||||
version "7.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz#44274d655eb3f1af3f3a574ba819d3f48caf99d5"
|
||||
@ -817,7 +839,7 @@
|
||||
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/preset-env@^7.16.11", "@babel/preset-env@^7.17.10":
|
||||
"@babel/preset-env@^7.16.11", "@babel/preset-env@^7.17.10", "@babel/preset-env@^7.18.0":
|
||||
version "7.18.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.2.tgz#f47d3000a098617926e674c945d95a28cb90977a"
|
||||
integrity sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q==
|
||||
@ -909,7 +931,19 @@
|
||||
"@babel/types" "^7.4.4"
|
||||
esutils "^2.0.2"
|
||||
|
||||
"@babel/preset-typescript@^7.16.7":
|
||||
"@babel/preset-react@^7.17.12":
|
||||
version "7.17.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.17.12.tgz#62adbd2d1870c0de3893095757ed5b00b492ab3d"
|
||||
integrity sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.17.12"
|
||||
"@babel/helper-validator-option" "^7.16.7"
|
||||
"@babel/plugin-transform-react-display-name" "^7.16.7"
|
||||
"@babel/plugin-transform-react-jsx" "^7.17.12"
|
||||
"@babel/plugin-transform-react-jsx-development" "^7.16.7"
|
||||
"@babel/plugin-transform-react-pure-annotations" "^7.16.7"
|
||||
|
||||
"@babel/preset-typescript@^7.16.7", "@babel/preset-typescript@^7.17.12":
|
||||
version "7.17.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz#40269e0a0084d56fc5731b6c40febe1c9a4a3e8c"
|
||||
integrity sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg==
|
||||
@ -2837,7 +2871,7 @@
|
||||
"@standardnotes/services" "^1.13.11"
|
||||
"@standardnotes/utils" "^1.6.10"
|
||||
|
||||
"@standardnotes/icons@^1.1.8":
|
||||
"@standardnotes/icons@^1.1.7", "@standardnotes/icons@^1.1.8":
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/icons/-/icons-1.1.8.tgz#958b73cc3dd68c7fe31dcceb8ee48627093ab468"
|
||||
integrity sha512-RhNzHEbSYFVwVz5+BqDAC5wJZ8DkQlboofwPxuTLSrmezjBeNi9kOw9metoC1Sf82u3bXJr5fgXAC8DEYXYKTg==
|
||||
|
Loading…
Reference in New Issue
Block a user