Merge branch 'develop' into feature/remove-batch-manager
This commit is contained in:
@@ -47,7 +47,9 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
|
|||||||
|
|
||||||
const onFormSubmit = async (event: Event) => {
|
const onFormSubmit = async (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
if (autocompleteSearchQuery !== '') {
|
||||||
await appState.noteTags.createAndAddNewTag();
|
await appState.noteTags.createAndAddNewTag();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeyDown = (event: KeyboardEvent) => {
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
@@ -115,8 +117,9 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
|
|||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
className={`${tags.length > 0 ? 'w-80' : 'w-70 mr-10'} sn-dropdown flex flex-col py-2 absolute`}
|
className={`${tags.length > 0 ? 'w-80' : 'w-70 mr-10'} sn-dropdown flex flex-col py-2 absolute`}
|
||||||
style={{ maxHeight: dropdownMaxHeight, maxWidth: tagsContainerMaxWidth }}
|
style={{ maxHeight: dropdownMaxHeight, maxWidth: tagsContainerMaxWidth }}
|
||||||
|
onBlur={closeOnBlur}
|
||||||
>
|
>
|
||||||
<div className="overflow-y-scroll">
|
<div className="overflow-y-auto">
|
||||||
{autocompleteTagResults.map((tagResult) => (
|
{autocompleteTagResults.map((tagResult) => (
|
||||||
<AutocompleteTagResult
|
<AutocompleteTagResult
|
||||||
key={tagResult.uuid}
|
key={tagResult.uuid}
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ const ConfirmSignoutContainer = observer((props: Props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const ConfirmSignoutModal = observer(({ application, appState }: Props) => {
|
const ConfirmSignoutModal = observer(({ application, appState }: Props) => {
|
||||||
const [deleteLocalBackups, setDeleteLocalBackups] = useState(
|
const [deleteLocalBackups, setDeleteLocalBackups] = useState(false);
|
||||||
application.hasAccount()
|
|
||||||
);
|
|
||||||
|
|
||||||
const cancelRef = useRef<HTMLButtonElement>();
|
const cancelRef = useRef<HTMLButtonElement>();
|
||||||
function close() {
|
function close() {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const NotesContextMenu = observer(({ appState }: Props) => {
|
|||||||
return appState.notes.contextMenuOpen ? (
|
return appState.notes.contextMenuOpen ? (
|
||||||
<div
|
<div
|
||||||
ref={contextMenuRef}
|
ref={contextMenuRef}
|
||||||
className="sn-dropdown max-h-120 max-w-xs flex flex-col py-2 overflow-y-scroll fixed"
|
className="sn-dropdown min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto fixed"
|
||||||
style={{
|
style={{
|
||||||
...appState.notes.contextMenuPosition,
|
...appState.notes.contextMenuPosition,
|
||||||
maxHeight: appState.notes.contextMenuMaxHeight,
|
maxHeight: appState.notes.contextMenuMaxHeight,
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ export const NotesOptions = observer(
|
|||||||
maxHeight: tagsMenuMaxHeight,
|
maxHeight: tagsMenuMaxHeight,
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown flex flex-col py-2 max-h-120 max-w-xs fixed overflow-y-scroll"
|
className="sn-dropdown min-w-80 flex flex-col py-2 max-h-120 max-w-xs fixed overflow-y-auto"
|
||||||
>
|
>
|
||||||
{appState.tags.tags.map((tag) => (
|
{appState.tags.tags.map((tag) => (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
|||||||
...position,
|
...position,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown sn-dropdown--animated max-h-120 max-w-xs flex flex-col py-2 overflow-y-scroll fixed"
|
className="sn-dropdown sn-dropdown--animated min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto fixed"
|
||||||
|
onBlur={closeOnBlur}
|
||||||
>
|
>
|
||||||
{open && (
|
{open && (
|
||||||
<NotesOptions
|
<NotesOptions
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ const SearchOptions = observer(({ appState }: Props) => {
|
|||||||
style={{
|
style={{
|
||||||
top: optionsPanelTop,
|
top: optionsPanelTop,
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown sn-dropdown--anchor-right sn-dropdown--animated absolute grid gap-2 py-2"
|
className="sn-dropdown sn-dropdown--anchor-right sn-dropdown--animated min-w-80 absolute grid gap-2 py-2"
|
||||||
|
onBlur={closeOnBlur}
|
||||||
>
|
>
|
||||||
<Switch
|
<Switch
|
||||||
className="h-10"
|
className="h-10"
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ const SessionsModal: FunctionComponent<{
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dialog onDismiss={close} className="sessions-modal">
|
<Dialog onDismiss={close} className="sessions-modal h-90vh">
|
||||||
<div className="sk-modal-content">
|
<div className="sk-modal-content">
|
||||||
<div class="sn-component">
|
<div class="sn-component">
|
||||||
<div class="sk-panel">
|
<div class="sk-panel">
|
||||||
@@ -145,7 +145,7 @@ const SessionsModal: FunctionComponent<{
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sk-panel-content">
|
<div class="sk-panel-content overflow-y-auto">
|
||||||
{refreshing ? (
|
{refreshing ? (
|
||||||
<>
|
<>
|
||||||
<div class="sk-spinner small info"></div>
|
<div class="sk-spinner small info"></div>
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { ApplicationService } from '@standardnotes/snjs';
|
import { ApplicationService } from '@standardnotes/snjs';
|
||||||
import { WebApplication } from '@/ui_models/application';
|
|
||||||
import { isDesktopApplication } from '@/utils';
|
import { isDesktopApplication } from '@/utils';
|
||||||
import { AppStateEvent } from '@/ui_models/app_state';
|
|
||||||
|
|
||||||
const MILLISECONDS_PER_SECOND = 1000;
|
const MILLISECONDS_PER_SECOND = 1000;
|
||||||
const FOCUS_POLL_INTERVAL = 1 * MILLISECONDS_PER_SECOND;
|
const POLL_INTERVAL = 50;
|
||||||
const LOCK_INTERVAL_NONE = 0;
|
const LOCK_INTERVAL_NONE = 0;
|
||||||
const LOCK_INTERVAL_IMMEDIATE = 1;
|
const LOCK_INTERVAL_IMMEDIATE = 1;
|
||||||
const LOCK_INTERVAL_ONE_MINUTE = 60 * MILLISECONDS_PER_SECOND;
|
const LOCK_INTERVAL_ONE_MINUTE = 60 * MILLISECONDS_PER_SECOND;
|
||||||
@@ -15,37 +13,21 @@ const STORAGE_KEY_AUTOLOCK_INTERVAL = "AutoLockIntervalKey";
|
|||||||
|
|
||||||
export class AutolockService extends ApplicationService {
|
export class AutolockService extends ApplicationService {
|
||||||
|
|
||||||
private unsubState?: () => void;
|
private pollInterval: any
|
||||||
private pollFocusInterval: any
|
|
||||||
private lastFocusState?: 'hidden' | 'visible'
|
private lastFocusState?: 'hidden' | 'visible'
|
||||||
private lockAfterDate?: Date
|
private lockAfterDate?: Date
|
||||||
private lockTimeout?: any
|
|
||||||
|
|
||||||
onAppLaunch() {
|
onAppLaunch() {
|
||||||
this.observeVisibility();
|
if (!isDesktopApplication()) {
|
||||||
|
this.beginPolling();
|
||||||
|
}
|
||||||
return super.onAppLaunch();
|
return super.onAppLaunch();
|
||||||
}
|
}
|
||||||
|
|
||||||
observeVisibility() {
|
|
||||||
this.unsubState = (this.application as WebApplication).getAppState().addObserver(
|
|
||||||
async (eventName) => {
|
|
||||||
if (eventName === AppStateEvent.WindowDidBlur) {
|
|
||||||
this.documentVisibilityChanged(false);
|
|
||||||
} else if (eventName === AppStateEvent.WindowDidFocus) {
|
|
||||||
this.documentVisibilityChanged(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (!isDesktopApplication()) {
|
|
||||||
this.beginWebFocusPolling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit() {
|
deinit() {
|
||||||
this.unsubState?.();
|
|
||||||
this.cancelAutoLockTimer();
|
this.cancelAutoLockTimer();
|
||||||
if (this.pollFocusInterval) {
|
if (this.pollInterval) {
|
||||||
clearInterval(this.pollFocusInterval);
|
clearInterval(this.pollInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,11 +67,15 @@ export class AutolockService extends ApplicationService {
|
|||||||
* Verify document is in focus every so often as visibilitychange event is
|
* Verify document is in focus every so often as visibilitychange event is
|
||||||
* not triggered on a typical window blur event but rather on tab changes.
|
* not triggered on a typical window blur event but rather on tab changes.
|
||||||
*/
|
*/
|
||||||
beginWebFocusPolling() {
|
beginPolling() {
|
||||||
this.pollFocusInterval = setInterval(() => {
|
this.pollInterval = setInterval(async () => {
|
||||||
if (document.hidden) {
|
const locked = await this.application.isLocked();
|
||||||
/** Native event listeners will have fired */
|
if (
|
||||||
return;
|
!locked &&
|
||||||
|
this.lockAfterDate &&
|
||||||
|
new Date() > this.lockAfterDate
|
||||||
|
) {
|
||||||
|
this.lockApplication();
|
||||||
}
|
}
|
||||||
const hasFocus = document.hasFocus();
|
const hasFocus = document.hasFocus();
|
||||||
if (hasFocus && this.lastFocusState === 'hidden') {
|
if (hasFocus && this.lastFocusState === 'hidden') {
|
||||||
@@ -99,7 +85,7 @@ export class AutolockService extends ApplicationService {
|
|||||||
}
|
}
|
||||||
/* Save this to compare against next time around */
|
/* Save this to compare against next time around */
|
||||||
this.lastFocusState = hasFocus ? 'visible' : 'hidden';
|
this.lastFocusState = hasFocus ? 'visible' : 'hidden';
|
||||||
}, FOCUS_POLL_INTERVAL);
|
}, POLL_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAutoLockIntervalOptions() {
|
getAutoLockIntervalOptions() {
|
||||||
@@ -129,14 +115,6 @@ export class AutolockService extends ApplicationService {
|
|||||||
|
|
||||||
async documentVisibilityChanged(visible: boolean) {
|
async documentVisibilityChanged(visible: boolean) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
const locked = await this.application.isLocked();
|
|
||||||
if (
|
|
||||||
!locked &&
|
|
||||||
this.lockAfterDate &&
|
|
||||||
new Date() > this.lockAfterDate
|
|
||||||
) {
|
|
||||||
this.lockApplication();
|
|
||||||
}
|
|
||||||
this.cancelAutoLockTimer();
|
this.cancelAutoLockTimer();
|
||||||
} else {
|
} else {
|
||||||
this.beginAutoLockTimer();
|
this.beginAutoLockTimer();
|
||||||
@@ -148,29 +126,15 @@ export class AutolockService extends ApplicationService {
|
|||||||
if (interval === LOCK_INTERVAL_NONE) {
|
if (interval === LOCK_INTERVAL_NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Use a timeout if possible, but if the computer is put to sleep, timeouts won't
|
|
||||||
* work. Need to set a date as backup. this.lockAfterDate does not need to be
|
|
||||||
* persisted, as living in memory is sufficient. If memory is cleared, then the
|
|
||||||
* application will lock anyway.
|
|
||||||
*/
|
|
||||||
const addToNow = (seconds: number) => {
|
const addToNow = (seconds: number) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
date.setSeconds(date.getSeconds() + seconds);
|
date.setSeconds(date.getSeconds() + seconds);
|
||||||
return date;
|
return date;
|
||||||
};
|
};
|
||||||
this.lockAfterDate = addToNow(interval / MILLISECONDS_PER_SECOND);
|
this.lockAfterDate = addToNow(interval / MILLISECONDS_PER_SECOND);
|
||||||
clearTimeout(this.lockTimeout);
|
|
||||||
this.lockTimeout = setTimeout(() => {
|
|
||||||
this.cancelAutoLockTimer();
|
|
||||||
this.lockApplication();
|
|
||||||
this.lockAfterDate = undefined;
|
|
||||||
}, interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelAutoLockTimer() {
|
cancelAutoLockTimer() {
|
||||||
clearTimeout(this.lockTimeout);
|
|
||||||
this.lockAfterDate = undefined;
|
this.lockAfterDate = undefined;
|
||||||
this.lockTimeout = undefined;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export class AppState {
|
|||||||
this.noAccountWarning.reset();
|
this.noAccountWarning.reset();
|
||||||
}
|
}
|
||||||
this.actionsMenu.reset();
|
this.actionsMenu.reset();
|
||||||
this.unsubApp();
|
this.unsubApp?.();
|
||||||
this.unsubApp = undefined;
|
this.unsubApp = undefined;
|
||||||
this.observers.length = 0;
|
this.observers.length = 0;
|
||||||
this.appEventObserverRemovers.forEach((remover) => remover());
|
this.appEventObserverRemovers.forEach((remover) => remover());
|
||||||
|
|||||||
@@ -198,9 +198,15 @@ export class NoteTagsState {
|
|||||||
async removeTagFromActiveNote(tag: SNTag): Promise<void> {
|
async removeTagFromActiveNote(tag: SNTag): Promise<void> {
|
||||||
const { activeNote } = this;
|
const { activeNote } = this;
|
||||||
if (activeNote) {
|
if (activeNote) {
|
||||||
|
const descendantTags = this.application.getTagDescendants(tag);
|
||||||
|
const tagsToRemove = [...descendantTags, tag];
|
||||||
|
await Promise.all(
|
||||||
|
tagsToRemove.map(async (tag) => {
|
||||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||||
mutator.removeItemAsRelationship(activeNote);
|
mutator.removeItemAsRelationship(activeNote);
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
this.application.sync();
|
this.application.sync();
|
||||||
this.reloadTags();
|
this.reloadTags();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,13 +346,18 @@ export class NotesState {
|
|||||||
|
|
||||||
async removeTagFromSelectedNotes(tag: SNTag): Promise<void> {
|
async removeTagFromSelectedNotes(tag: SNTag): Promise<void> {
|
||||||
const selectedNotes = Object.values(this.selectedNotes);
|
const selectedNotes = Object.values(this.selectedNotes);
|
||||||
|
const descendantTags = this.application.getTagDescendants(tag);
|
||||||
|
const tagsToRemove = [...descendantTags, tag];
|
||||||
|
await Promise.all(
|
||||||
|
tagsToRemove.map(async (tag) => {
|
||||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||||
for (const note of selectedNotes) {
|
for (const note of selectedNotes) {
|
||||||
mutator.removeItemAsRelationship(note);
|
mutator.removeItemAsRelationship(note);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
this.application.sync();
|
this.application.sync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isTagInSelectedNotes(tag: SNTag): boolean {
|
isTagInSelectedNotes(tag: SNTag): boolean {
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit(): void {
|
deinit(): void {
|
||||||
this.unsubApp();
|
this.unsubApp?.();
|
||||||
this.unsubState();
|
this.unsubState?.();
|
||||||
for (const disposer of this.reactionDisposers) {
|
for (const disposer of this.reactionDisposers) {
|
||||||
disposer();
|
disposer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,10 +289,10 @@ class TagsViewCtrl extends PureViewCtrl<unknown, TagState> {
|
|||||||
|
|
||||||
async saveTag($event: Event, tag: SNTag) {
|
async saveTag($event: Event, tag: SNTag) {
|
||||||
($event.target! as HTMLInputElement).blur();
|
($event.target! as HTMLInputElement).blur();
|
||||||
|
if (this.getState().templateTag) {
|
||||||
if (!this.titles[tag.uuid]?.length) {
|
if (!this.titles[tag.uuid]?.length) {
|
||||||
return this.undoCreateTag(tag);
|
return this.undoCreateTag(tag);
|
||||||
}
|
}
|
||||||
if (this.getState().templateTag) {
|
|
||||||
return this.saveNewTag();
|
return this.saveNewTag();
|
||||||
} else {
|
} else {
|
||||||
return this.saveTagRename(tag);
|
return this.saveTagRename(tag);
|
||||||
@@ -314,6 +314,9 @@ class TagsViewCtrl extends PureViewCtrl<unknown, TagState> {
|
|||||||
if (newTitle.length === 0) {
|
if (newTitle.length === 0) {
|
||||||
this.titles[tag.uuid] = this.editingOriginalName;
|
this.titles[tag.uuid] = this.editingOriginalName;
|
||||||
this.editingOriginalName = undefined;
|
this.editingOriginalName = undefined;
|
||||||
|
await this.setState({
|
||||||
|
editingTag: undefined
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const existingTag = this.application.findTagByTitle(newTitle);
|
const existingTag = this.application.findTagByTitle(newTitle);
|
||||||
@@ -345,6 +348,7 @@ class TagsViewCtrl extends PureViewCtrl<unknown, TagState> {
|
|||||||
this.application.alertService!.alert(
|
this.application.alertService!.alert(
|
||||||
"A tag with this name already exists."
|
"A tag with this name already exists."
|
||||||
);
|
);
|
||||||
|
this.undoCreateTag(newTag);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const insertedTag = await this.application.insertItem(newTag);
|
const insertedTag = await this.application.insertItem(newTag);
|
||||||
|
|||||||
@@ -109,6 +109,11 @@
|
|||||||
padding-bottom: 0.375rem;
|
padding-bottom: 0.375rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.py-8 {
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.outline-none {
|
.outline-none {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
@@ -254,6 +259,10 @@
|
|||||||
height: 4.5rem;
|
height: 4.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-90vh {
|
||||||
|
height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
.max-h-120 {
|
.max-h-120 {
|
||||||
max-height: 30rem;
|
max-height: 30rem;
|
||||||
}
|
}
|
||||||
@@ -266,8 +275,8 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overflow-y-scroll {
|
.overflow-y-auto {
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overflow-auto {
|
.overflow-auto {
|
||||||
@@ -351,7 +360,6 @@
|
|||||||
|
|
||||||
.sn-dropdown {
|
.sn-dropdown {
|
||||||
@extend .bg-default;
|
@extend .bg-default;
|
||||||
// @extend .min-w-80;
|
|
||||||
@extend .rounded;
|
@extend .rounded;
|
||||||
@extend .box-shadow;
|
@extend .box-shadow;
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> .title {
|
> .title {
|
||||||
|
@extend .focus\:outline-none;
|
||||||
|
@extend .focus\:shadow-none;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "standard-notes-web",
|
"name": "standard-notes-web",
|
||||||
"version": "3.9.0-beta01",
|
"version": "3.8.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"@reach/checkbox": "^0.13.2",
|
"@reach/checkbox": "^0.13.2",
|
||||||
"@reach/dialog": "^0.13.0",
|
"@reach/dialog": "^0.13.0",
|
||||||
"@standardnotes/sncrypto-web": "1.2.10",
|
"@standardnotes/sncrypto-web": "1.2.10",
|
||||||
"@standardnotes/snjs": "2.6.0",
|
"@standardnotes/snjs": "2.6.3",
|
||||||
"mobx": "^6.1.6",
|
"mobx": "^6.1.6",
|
||||||
"mobx-react-lite": "^3.2.0",
|
"mobx-react-lite": "^3.2.0",
|
||||||
"preact": "^10.5.12"
|
"preact": "^10.5.12"
|
||||||
|
|||||||
@@ -1936,10 +1936,10 @@
|
|||||||
"@standardnotes/sncrypto-common" "^1.2.7"
|
"@standardnotes/sncrypto-common" "^1.2.7"
|
||||||
libsodium-wrappers "^0.7.8"
|
libsodium-wrappers "^0.7.8"
|
||||||
|
|
||||||
"@standardnotes/snjs@2.6.0":
|
"@standardnotes/snjs@2.6.3":
|
||||||
version "2.6.0"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.6.0.tgz#8ebdfcb0918c308198b38a63d7aa946387b83ac4"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.6.3.tgz#7677899c050b0616d994423fd4ec9caf03394f35"
|
||||||
integrity sha512-Gb/kAdMtjVlSiQH7pkDzFxKtIrrY43i2hSejO2c+zCviZspiDZPpXLpEhMJ295ow2tluhOf8zfBUda3LMC6oDw==
|
integrity sha512-5pWh+BPVPpd6JlP3avo2puGk9EWUaH0+6Y1fN9rMR8oLZ2oc8Dffiy5S4TLNm8zL4q504oMlm1/ALkwwZpKLEQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth" "^2.0.0"
|
"@standardnotes/auth" "^2.0.0"
|
||||||
"@standardnotes/sncrypto-common" "^1.2.9"
|
"@standardnotes/sncrypto-common" "^1.2.9"
|
||||||
|
|||||||
Reference in New Issue
Block a user