Merge remote-tracking branch 'upstream/develop' into account-menu-splitted
# Conflicts: # app/assets/stylesheets/_sn.scss
This commit is contained in:
@@ -9,7 +9,6 @@ SECRET_KEY_BASE=test
|
|||||||
APP_HOST=http://localhost:3001
|
APP_HOST=http://localhost:3001
|
||||||
|
|
||||||
EXTENSIONS_MANAGER_LOCATION=extensions/extensions-manager/dist/index.html
|
EXTENSIONS_MANAGER_LOCATION=extensions/extensions-manager/dist/index.html
|
||||||
BATCH_MANAGER_LOCATION=extensions/batch-manager/dist/index.min.html
|
|
||||||
SF_DEFAULT_SERVER=http://localhost:3000
|
SF_DEFAULT_SERVER=http://localhost:3000
|
||||||
SF_NEXT_VERSION_SERVER=http://localhost:3000
|
SF_NEXT_VERSION_SERVER=http://localhost:3000
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ SF_NEXT_VERSION_SERVER=http://localhost:3000
|
|||||||
DEV_DEFAULT_SYNC_SERVER=https://sync.standardnotes.org
|
DEV_DEFAULT_SYNC_SERVER=https://sync.standardnotes.org
|
||||||
DEV_NEXT_VERSION_SYNC_SERVER=https://api.standardnotes.com
|
DEV_NEXT_VERSION_SYNC_SERVER=https://api.standardnotes.com
|
||||||
DEV_EXTENSIONS_MANAGER_LOCATION=public/extensions/extensions-manager/dist/index.html
|
DEV_EXTENSIONS_MANAGER_LOCATION=public/extensions/extensions-manager/dist/index.html
|
||||||
DEV_BATCH_MANAGER_LOCATION=public/extensions/batch-manager/dist/index.min.html
|
|
||||||
|
|
||||||
# NewRelic (Optional)
|
# NewRelic (Optional)
|
||||||
NEW_RELIC_ENABLED=false
|
NEW_RELIC_ENABLED=false
|
||||||
|
|||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -7,6 +7,4 @@
|
|||||||
[submodule "public/extensions/extensions-manager"]
|
[submodule "public/extensions/extensions-manager"]
|
||||||
path = public/extensions/extensions-manager
|
path = public/extensions/extensions-manager
|
||||||
url = https://github.com/sn-extensions/extensions-manager.git
|
url = https://github.com/sn-extensions/extensions-manager.git
|
||||||
[submodule "public/extensions/batch-manager"]
|
|
||||||
path = public/extensions/batch-manager
|
|
||||||
url = https://github.com/sn-extensions/batch-manager.git
|
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ The web app makes use of two optional native extensions, which, when running the
|
|||||||
1. Set the following environment variables in the .env file:
|
1. Set the following environment variables in the .env file:
|
||||||
```
|
```
|
||||||
EXTENSIONS_MANAGER_LOCATION=extensions/extensions-manager/dist/index.html
|
EXTENSIONS_MANAGER_LOCATION=extensions/extensions-manager/dist/index.html
|
||||||
BATCH_MANAGER_LOCATION=extensions/batch-manager/dist/index.min.html
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also set the `SF_DEFAULT_SERVER` and `SF_NEXT_VERSION_SERVER` environment variables to set the default servers for login and registration.
|
You can also set the `SF_DEFAULT_SERVER` and `SF_NEXT_VERSION_SERVER` environment variables to set the default servers for login and registration.
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
|
|||||||
<Disclosure open={dropdownVisible} onChange={showDropdown}>
|
<Disclosure open={dropdownVisible} onChange={showDropdown}>
|
||||||
<input
|
<input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
className={`${tags.length > 0 ? 'w-80' : 'w-70 mr-10'} bg-default text-xs
|
className={`${tags.length > 0 ? 'w-80' : 'w-70 mr-10'} bg-transparent text-xs
|
||||||
color-text no-border h-7 focus:outline-none focus:shadow-none focus:border-bottom`}
|
color-text no-border h-7 focus:outline-none focus:shadow-none focus:border-bottom`}
|
||||||
value={autocompleteSearchQuery}
|
value={autocompleteSearchQuery}
|
||||||
onChange={onSearchQueryChange}
|
onChange={onSearchQueryChange}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const NoteTagsContainer = observer(({ appState }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="bg-default flex flex-wrap min-w-80 -mt-1 -mr-2"
|
className="bg-transparent flex flex-wrap min-w-80 -mt-1 -mr-2"
|
||||||
style={{
|
style={{
|
||||||
maxWidth: tagsContainerMaxWidth,
|
maxWidth: tagsContainerMaxWidth,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
|||||||
maxHeight,
|
maxHeight,
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown sn-dropdown--animated min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto 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
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ const SearchOptions = observer(({ appState }: Props) => {
|
|||||||
top: optionsPanelTop,
|
top: optionsPanelTop,
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown sn-dropdown--anchor-right sn-dropdown--animated min-w-80 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"
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ import {
|
|||||||
FillItemContent,
|
FillItemContent,
|
||||||
ComponentMutator,
|
ComponentMutator,
|
||||||
Copy,
|
Copy,
|
||||||
dictToArray
|
PayloadContent,
|
||||||
, PayloadContent , ComponentPermission } from '@standardnotes/snjs';
|
ComponentPermission } from '@standardnotes/snjs';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** A class for handling installation of system extensions */
|
/** A class for handling installation of system extensions */
|
||||||
export class NativeExtManager extends ApplicationService {
|
export class NativeExtManager extends ApplicationService {
|
||||||
extManagerId = 'org.standardnotes.extensions-manager';
|
extManagerId = 'org.standardnotes.extensions-manager';
|
||||||
batchManagerId = 'org.standardnotes.batch-manager';
|
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async onAppLaunch() {
|
async onAppLaunch() {
|
||||||
@@ -32,14 +29,6 @@ export class NativeExtManager extends ApplicationService {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
get batchManagerPred() {
|
|
||||||
const batchMgrId = 'org.standardnotes.batch-manager';
|
|
||||||
return SNPredicate.CompoundPredicate([
|
|
||||||
new SNPredicate('content_type', '=', ContentType.Component),
|
|
||||||
new SNPredicate('package_info.identifier', '=', batchMgrId)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
get extMgrUrl() {
|
get extMgrUrl() {
|
||||||
return (window as any)._extensions_manager_location;
|
return (window as any)._extensions_manager_location;
|
||||||
}
|
}
|
||||||
@@ -50,9 +39,7 @@ export class NativeExtManager extends ApplicationService {
|
|||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.application!.singletonManager!.registerPredicate(this.extManagerPred);
|
this.application!.singletonManager!.registerPredicate(this.extManagerPred);
|
||||||
this.application!.singletonManager!.registerPredicate(this.batchManagerPred);
|
|
||||||
this.resolveExtensionsManager();
|
this.resolveExtensionsManager();
|
||||||
this.resolveBatchManager();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async resolveExtensionsManager() {
|
async resolveExtensionsManager() {
|
||||||
@@ -132,75 +119,4 @@ export class NativeExtManager extends ApplicationService {
|
|||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
async resolveBatchManager() {
|
|
||||||
const batchManager = (await this.application!.singletonManager!.findOrCreateSingleton(
|
|
||||||
this.batchManagerPred,
|
|
||||||
ContentType.Component,
|
|
||||||
this.batchManagerTemplateContent()
|
|
||||||
)) as SNComponent;
|
|
||||||
let needsSync = false;
|
|
||||||
if (isDesktopApplication()) {
|
|
||||||
if (!batchManager.local_url) {
|
|
||||||
await this.application!.changeItem(batchManager.uuid, (m) => {
|
|
||||||
const mutator = m as ComponentMutator;
|
|
||||||
mutator.local_url = this.batchMgrUrl;
|
|
||||||
});
|
|
||||||
needsSync = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!batchManager.hosted_url) {
|
|
||||||
await this.application!.changeItem(batchManager.uuid, (m) => {
|
|
||||||
const mutator = m as ComponentMutator;
|
|
||||||
mutator.hosted_url = this.batchMgrUrl;
|
|
||||||
});
|
|
||||||
needsSync = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle addition of SN|ExtensionRepo permission
|
|
||||||
const permissions = Copy(batchManager!.permissions) as ComponentPermission[];
|
|
||||||
const permission = permissions.find((p) => {
|
|
||||||
return p.name === ComponentAction.StreamItems;
|
|
||||||
});
|
|
||||||
if (permission && !permission.content_types!.includes(ContentType.ExtensionRepo)) {
|
|
||||||
permission.content_types!.push(ContentType.ExtensionRepo);
|
|
||||||
await this.application!.changeItem(batchManager.uuid, (m) => {
|
|
||||||
const mutator = m as ComponentMutator;
|
|
||||||
mutator.permissions = permissions;
|
|
||||||
});
|
|
||||||
needsSync = true;
|
|
||||||
}
|
|
||||||
if (needsSync) {
|
|
||||||
this.application!.saveItem(batchManager.uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
batchManagerTemplateContent() {
|
|
||||||
const url = this.batchMgrUrl;
|
|
||||||
if (!url) {
|
|
||||||
throw Error('window._batch_manager_location must be set.');
|
|
||||||
}
|
|
||||||
const packageInfo = {
|
|
||||||
name: 'Batch Manager',
|
|
||||||
identifier: this.batchManagerId
|
|
||||||
};
|
|
||||||
const allContentType = dictToArray(ContentType);
|
|
||||||
const content = FillItemContent({
|
|
||||||
name: packageInfo.name,
|
|
||||||
area: 'modal',
|
|
||||||
package_info: packageInfo,
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
name: ComponentAction.StreamItems,
|
|
||||||
content_types: allContentType
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
if (isDesktopApplication()) {
|
|
||||||
content.local_url = this.batchMgrUrl;
|
|
||||||
} else {
|
|
||||||
content.hosted_url = this.batchMgrUrl;
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,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) {
|
||||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
const descendantTags = this.application.getTagDescendants(tag);
|
||||||
mutator.removeItemAsRelationship(activeNote);
|
const tagsToRemove = [...descendantTags, tag];
|
||||||
});
|
await Promise.all(
|
||||||
|
tagsToRemove.map(async (tag) => {
|
||||||
|
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||||
|
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);
|
||||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
const descendantTags = this.application.getTagDescendants(tag);
|
||||||
for (const note of selectedNotes) {
|
const tagsToRemove = [...descendantTags, tag];
|
||||||
mutator.removeItemAsRelationship(note);
|
await Promise.all(
|
||||||
}
|
tagsToRemove.map(async (tag) => {
|
||||||
});
|
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||||
|
for (const note of selectedNotes) {
|
||||||
|
mutator.removeItemAsRelationship(note);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
this.application.sync();
|
this.application.sync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isTagInSelectedNotes(tag: SNTag): boolean {
|
isTagInSelectedNotes(tag: SNTag): boolean {
|
||||||
|
|||||||
@@ -213,11 +213,6 @@ export class WebApplication extends SNApplication {
|
|||||||
|
|
||||||
async openModalComponent(component: SNComponent): Promise<void> {
|
async openModalComponent(component: SNComponent): Promise<void> {
|
||||||
switch (component.package_info?.identifier) {
|
switch (component.package_info?.identifier) {
|
||||||
case 'org.standardnotes.batch-manager':
|
|
||||||
if (!await this.authorizeBatchManagerAccess()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'org.standardnotes.cloudlink':
|
case 'org.standardnotes.cloudlink':
|
||||||
if (!await this.authorizeCloudLinkAccess()) {
|
if (!await this.authorizeCloudLinkAccess()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,328 +1,9 @@
|
|||||||
/* Components and utilities that are good candidates for extraction to StyleKit. */
|
/* Components and utilities that are good candidates for extraction to StyleKit. */
|
||||||
|
|
||||||
.border-2 {
|
|
||||||
border-width: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-b-1 {
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-background {
|
|
||||||
border-color: var(--sn-stylekit-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-transparent {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-info {
|
|
||||||
border-color: var(--sn-stylekit-info-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-neutral {
|
|
||||||
border-color: var(--sn-stylekit-neutral-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-border {
|
|
||||||
background-color: var(--sn-stylekit-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-clip-padding {
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-neutral {
|
|
||||||
background-color: var(--sn-stylekit-neutral-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus-within\:border-background:focus-within {
|
|
||||||
border-color: var(--sn-stylekit-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:border-bottom:focus {
|
|
||||||
border-bottom: 2px solid var(--sn-stylekit-info-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.justify-start {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-2 {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-1 {
|
|
||||||
margin-left: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-1 {
|
|
||||||
margin-right: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-10 {
|
|
||||||
margin-right: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-mt-1 {
|
|
||||||
margin-top: -0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-mr-1 {
|
|
||||||
margin-right: -0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-mr-2 {
|
|
||||||
margin-right: -0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-1 {
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
padding-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pl-1 {
|
|
||||||
padding-left: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pr-2 {
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.px-1 {
|
|
||||||
padding-left: 0.25rem;
|
|
||||||
padding-right: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.px-2 {
|
|
||||||
padding-left: 0.5rem;
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-1\.5 {
|
|
||||||
padding-top: 0.375rem;
|
|
||||||
padding-bottom: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-8 {
|
|
||||||
padding-top: 2rem;
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.outline-none {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-foreground {
|
|
||||||
color: var(--sn-stylekit-foreground-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-danger {
|
|
||||||
color: var(--sn-stylekit-danger-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-info {
|
|
||||||
color: var(--sn-stylekit-info-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ring-info {
|
|
||||||
box-shadow: 0 0 0 2px var(--sn-stylekit-info-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-ring-info {
|
|
||||||
box-shadow: inset 0 0 0 2px var(--sn-stylekit-info-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:bg-contrast:focus {
|
|
||||||
@extend .bg-contrast;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:color-text:hover {
|
|
||||||
@extend .color-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:color-text:focus {
|
|
||||||
@extend .color-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-secondary-contrast:hover {
|
|
||||||
@extend .bg-secondary-contrast;
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:bg-secondary-contrast:focus {
|
|
||||||
@extend .bg-secondary-contrast;
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:inner-ring-info:focus {
|
|
||||||
@extend .inner-ring-info;
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:ring-info:focus {
|
|
||||||
@extend .ring-info;
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus-within\:ring-info:focus-within {
|
|
||||||
@extend .ring-info;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-3xl {
|
|
||||||
font-size: 1.875rem;
|
|
||||||
line-height: 2.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-0 {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-3\.5 {
|
|
||||||
width: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-5 {
|
|
||||||
width: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-8 {
|
|
||||||
width: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-290px {
|
|
||||||
max-width: 290px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-xs {
|
|
||||||
max-width: 20rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-40 {
|
|
||||||
max-width: 10rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-w-5 {
|
|
||||||
min-width: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-w-40 {
|
|
||||||
min-width: 10rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-1px {
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-0 {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-3\.5 {
|
|
||||||
height: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-4\.5 {
|
|
||||||
height: 1.125rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-5 {
|
|
||||||
height: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-6 {
|
|
||||||
height: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-7 {
|
|
||||||
height: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-8 {
|
|
||||||
height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-9 {
|
|
||||||
height: 2.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-10 {
|
|
||||||
height: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-18 {
|
|
||||||
height: 4.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-90vh {
|
.h-90vh {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-h-120 {
|
|
||||||
max-height: 30rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-5 {
|
|
||||||
min-height: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fixed {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-y-auto {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-auto {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-ellipsis {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items-start {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-2 {
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-wrap {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whitespace-pre-wrap {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whitespace-nowrap {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-80 {
|
|
||||||
width: 20rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-70 {
|
|
||||||
width: 17.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A button that is just an icon. Separated from .sn-button because there
|
* A button that is just an icon. Separated from .sn-button because there
|
||||||
* is almost no style overlap.
|
* is almost no style overlap.
|
||||||
@@ -376,7 +57,7 @@
|
|||||||
&[data-state='collapsed'] {
|
&[data-state='collapsed'] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sn-dropdown--animated {
|
&.sn-dropdown--animated {
|
||||||
@extend .transition-transform;
|
@extend .transition-transform;
|
||||||
@extend .duration-150;
|
@extend .duration-150;
|
||||||
|
|||||||
@@ -32,14 +32,12 @@
|
|||||||
data-default-sync-server="<%= env.DEV_DEFAULT_SYNC_SERVER %>"
|
data-default-sync-server="<%= env.DEV_DEFAULT_SYNC_SERVER %>"
|
||||||
data-next-version-sync-server="<%= env.DEV_NEXT_VERSION_SYNC_SERVER %>"
|
data-next-version-sync-server="<%= env.DEV_NEXT_VERSION_SYNC_SERVER %>"
|
||||||
data-extensions-manager-location="<%= env.DEV_EXTENSIONS_MANAGER_LOCATION %>"
|
data-extensions-manager-location="<%= env.DEV_EXTENSIONS_MANAGER_LOCATION %>"
|
||||||
data-batch-manager-location="<%= env.DEV_BATCH_MANAGER_LOCATION %>"
|
|
||||||
data-bugsnag-api-key="<%= env.DEV_BUGSNAG_API_KEY %>"
|
data-bugsnag-api-key="<%= env.DEV_BUGSNAG_API_KEY %>"
|
||||||
>
|
>
|
||||||
<script>
|
<script>
|
||||||
window._default_sync_server = document.body.dataset.defaultSyncServer || "https://sync.standardnotes.org";
|
window._default_sync_server = document.body.dataset.defaultSyncServer || "https://sync.standardnotes.org";
|
||||||
window._next_version_sync_server = document.body.dataset.nextVersionSyncServer || "https://api.standardnotes.com";
|
window._next_version_sync_server = document.body.dataset.nextVersionSyncServer || "https://api.standardnotes.com";
|
||||||
window._extensions_manager_location = document.body.dataset.extensionsManagerLocation || "public/extensions/extensions-manager/dist/index.html";
|
window._extensions_manager_location = document.body.dataset.extensionsManagerLocation || "public/extensions/extensions-manager/dist/index.html";
|
||||||
window._batch_manager_location = document.body.dataset.batchManagerLocation || "public/extensions/batch-manager/dist/index.min.html";
|
|
||||||
window._bugsnag_api_key = document.body.dataset.bugsnagApiKey;
|
window._bugsnag_api_key = document.body.dataset.bugsnagApiKey;
|
||||||
</script>
|
</script>
|
||||||
<application-group-view />
|
<application-group-view />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "standard-notes-web",
|
"name": "standard-notes-web",
|
||||||
"version": "3.8.1",
|
"version": "3.8.2",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"pug-loader": "^2.4.0",
|
"pug-loader": "^2.4.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"serve-static": "^1.14.1",
|
"serve-static": "^1.14.1",
|
||||||
"sn-stylekit": "5.1.0",
|
"sn-stylekit": "5.2.1",
|
||||||
"ts-loader": "^8.0.17",
|
"ts-loader": "^8.0.17",
|
||||||
"typescript": "4.2.3",
|
"typescript": "4.2.3",
|
||||||
"typescript-eslint": "0.0.1-alpha.0",
|
"typescript-eslint": "0.0.1-alpha.0",
|
||||||
@@ -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.2",
|
"@standardnotes/snjs": "2.7.1",
|
||||||
"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"
|
||||||
|
|||||||
Submodule public/extensions/batch-manager deleted from 2d1ba6ac9f
16
yarn.lock
16
yarn.lock
@@ -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.2":
|
"@standardnotes/snjs@2.7.1":
|
||||||
version "2.6.2"
|
version "2.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.6.2.tgz#dbd835f8c0fcdf951f636b3a5b6d0b54c00de458"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.7.1.tgz#e8073942fe9a8f762989ab75df94407b9934ea3e"
|
||||||
integrity sha512-/6U9sEBtT2MouwbH0OBaQW4eqnvwwNnXUXq+zDfV8UKqJPoEnwLGumnb72cJ8d/67e0haoltc2C8wHicbZgFrQ==
|
integrity sha512-kCZU4Tx6vNYcEeh22ax8Vfr/LYEbgAqI9nSC6jB8MTg6nJzCuh4b/nngW+yVUz91phu156XN0YeMyj7HJ3DWVw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth" "^2.0.0"
|
"@standardnotes/auth" "^2.0.0"
|
||||||
"@standardnotes/sncrypto-common" "^1.2.9"
|
"@standardnotes/sncrypto-common" "^1.2.9"
|
||||||
@@ -7815,10 +7815,10 @@ slice-ansi@^4.0.0:
|
|||||||
astral-regex "^2.0.0"
|
astral-regex "^2.0.0"
|
||||||
is-fullwidth-code-point "^3.0.0"
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
|
||||||
sn-stylekit@5.1.0:
|
sn-stylekit@5.2.1:
|
||||||
version "5.1.0"
|
version "5.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/sn-stylekit/-/sn-stylekit-5.1.0.tgz#97ce7323834ff7f3645ed4463beb3ad4e42f7e7e"
|
resolved "https://registry.yarnpkg.com/sn-stylekit/-/sn-stylekit-5.2.1.tgz#d56a38017d6b45f5c2ebcf7b2c2db94c50a26e27"
|
||||||
integrity sha512-SjKJYGRnR1iCVtllqJyW9/gWV7V56MJrkXHEo5+C9Ch3syRRlG3k+AwC0vC8ms6PWxpHJUdCHLQROvFOBPQuCw==
|
integrity sha512-kupuH9XlPy5TuO2a2E+sLQnF41VQ0a4cwHRltNhQSI6O135n4HkkDYgyEAvy5DKcc0aun4KHy5mz9kYefQvciw==
|
||||||
|
|
||||||
snapdragon-node@^2.0.1:
|
snapdragon-node@^2.0.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user