refactor: update SNJS + eslint
This commit is contained in:
@@ -12,7 +12,9 @@
|
||||
| {{ctrl.challenge.subheading}}
|
||||
.sk-panel-section
|
||||
div(ng-repeat="prompt in ctrl.state.prompts track by prompt.id")
|
||||
.sk-panel-row
|
||||
.sk-panel-row(
|
||||
ng-if="prompt.validation != ctrl.protectionsSessionValidation"
|
||||
)
|
||||
input.sk-input.contrast(
|
||||
ng-model="ctrl.state.values[prompt.id].value"
|
||||
should-focus="$index == 0"
|
||||
@@ -21,7 +23,17 @@
|
||||
ng-change="ctrl.onTextValueChange(prompt)"
|
||||
ng-attr-type="{{prompt.secureTextEntry ? 'password' : 'text'}}",
|
||||
ng-attr-placeholder="{{prompt.title}}"
|
||||
)
|
||||
)
|
||||
.sk-horizontal-group(
|
||||
ng-if="prompt.validation == ctrl.protectionsSessionValidation"
|
||||
)
|
||||
.sk-p.sk-bold Remember For
|
||||
a.sk-a.info(
|
||||
ng-repeat="option in ctrl.protectionsSessionDurations"
|
||||
ng-class="{'boxed' : option.valueInSeconds == ctrl.state.values[prompt.id].value}"
|
||||
ng-click="ctrl.onValueChange(prompt, option.valueInSeconds);"
|
||||
)
|
||||
| {{option.label}}
|
||||
.sk-panel-row.centered
|
||||
label.sk-label.danger(
|
||||
ng-if="ctrl.state.values[prompt.id].invalid"
|
||||
|
||||
@@ -5,45 +5,46 @@ import {
|
||||
removeFromArray,
|
||||
Challenge,
|
||||
ChallengeReason,
|
||||
ChallengePrompt
|
||||
ChallengePrompt,
|
||||
ChallengeValidation,
|
||||
ProtectionSessionDurations,
|
||||
} from '@standardnotes/snjs';
|
||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||
import { WebDirective } from '@/types';
|
||||
import { confirmDialog } from '@/services/alertService';
|
||||
import {
|
||||
STRING_SIGN_OUT_CONFIRMATION,
|
||||
} from '@/strings';
|
||||
import { STRING_SIGN_OUT_CONFIRMATION } from '@/strings';
|
||||
|
||||
type InputValue = {
|
||||
prompt: ChallengePrompt
|
||||
value: string
|
||||
invalid: boolean
|
||||
}
|
||||
prompt: ChallengePrompt;
|
||||
value: string | number | boolean;
|
||||
invalid: boolean;
|
||||
};
|
||||
|
||||
type Values = Record<number, InputValue>
|
||||
type Values = Record<number, InputValue>;
|
||||
|
||||
type ChallengeModalState = {
|
||||
prompts: ChallengePrompt[]
|
||||
values: Partial<Values>
|
||||
processing: boolean,
|
||||
forgotPasscode: boolean,
|
||||
showForgotPasscodeLink: boolean,
|
||||
processingPrompts: ChallengePrompt[],
|
||||
hasAccount: boolean,
|
||||
}
|
||||
prompts: ChallengePrompt[];
|
||||
values: Partial<Values>;
|
||||
processing: boolean;
|
||||
forgotPasscode: boolean;
|
||||
showForgotPasscodeLink: boolean;
|
||||
processingPrompts: ChallengePrompt[];
|
||||
hasAccount: boolean;
|
||||
protectedNoteAccessDuration: number;
|
||||
};
|
||||
|
||||
class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
private $element: JQLite
|
||||
application!: WebApplication
|
||||
challenge!: Challenge
|
||||
class ChallengeModalCtrl extends PureViewCtrl<unknown, ChallengeModalState> {
|
||||
application!: WebApplication;
|
||||
challenge!: Challenge;
|
||||
|
||||
/** @template */
|
||||
protectionsSessionDurations = ProtectionSessionDurations;
|
||||
protectionsSessionValidation =
|
||||
ChallengeValidation.ProtectionSessionDuration;
|
||||
|
||||
/* @ngInject */
|
||||
constructor(
|
||||
$element: JQLite,
|
||||
$timeout: ng.ITimeoutService
|
||||
) {
|
||||
constructor(private $element: JQLite, $timeout: ng.ITimeoutService) {
|
||||
super($timeout);
|
||||
this.$element = $element;
|
||||
}
|
||||
|
||||
getState() {
|
||||
@@ -57,13 +58,13 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
for (const prompt of prompts) {
|
||||
values[prompt.id] = {
|
||||
prompt,
|
||||
value: '',
|
||||
invalid: false
|
||||
value: prompt.initialValue ?? '',
|
||||
invalid: false,
|
||||
};
|
||||
}
|
||||
const showForgotPasscodeLink = [
|
||||
ChallengeReason.ApplicationUnlock,
|
||||
ChallengeReason.Migration
|
||||
ChallengeReason.Migration,
|
||||
].includes(this.challenge.reason);
|
||||
this.setState({
|
||||
prompts,
|
||||
@@ -72,34 +73,32 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
forgotPasscode: false,
|
||||
showForgotPasscodeLink,
|
||||
hasAccount: this.application.hasAccount(),
|
||||
processingPrompts: []
|
||||
processingPrompts: [],
|
||||
protectedNoteAccessDuration: ProtectionSessionDurations[0].valueInSeconds,
|
||||
});
|
||||
this.application.addChallengeObserver(
|
||||
this.challenge,
|
||||
{
|
||||
onValidValue: (value) => {
|
||||
this.getState().values[value.prompt.id]!.invalid = false;
|
||||
this.application.addChallengeObserver(this.challenge, {
|
||||
onValidValue: (value) => {
|
||||
this.getState().values[value.prompt.id]!.invalid = false;
|
||||
removeFromArray(this.state.processingPrompts, value.prompt);
|
||||
this.reloadProcessingStatus();
|
||||
},
|
||||
onInvalidValue: (value) => {
|
||||
this.getState().values[value.prompt.id]!.invalid = true;
|
||||
/** If custom validation, treat all values together and not individually */
|
||||
if (!value.prompt.validates) {
|
||||
this.setState({ processingPrompts: [], processing: false });
|
||||
} else {
|
||||
removeFromArray(this.state.processingPrompts, value.prompt);
|
||||
this.reloadProcessingStatus();
|
||||
},
|
||||
onInvalidValue: (value) => {
|
||||
this.getState().values[value.prompt.id]!.invalid = true;
|
||||
/** If custom validation, treat all values together and not individually */
|
||||
if (!value.prompt.validates) {
|
||||
this.setState({ processingPrompts: [], processing: false });
|
||||
} else {
|
||||
removeFromArray(this.state.processingPrompts, value.prompt);
|
||||
this.reloadProcessingStatus();
|
||||
}
|
||||
},
|
||||
onComplete: () => {
|
||||
this.dismiss();
|
||||
},
|
||||
onCancel: () => {
|
||||
this.dismiss();
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
onComplete: () => {
|
||||
this.dismiss();
|
||||
},
|
||||
onCancel: () => {
|
||||
this.dismiss();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
deinit() {
|
||||
@@ -110,18 +109,20 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
|
||||
reloadProcessingStatus() {
|
||||
return this.setState({
|
||||
processing: this.state.processingPrompts.length > 0
|
||||
processing: this.state.processingPrompts.length > 0,
|
||||
});
|
||||
}
|
||||
|
||||
async destroyLocalData() {
|
||||
if (await confirmDialog({
|
||||
text: STRING_SIGN_OUT_CONFIRMATION,
|
||||
confirmButtonStyle: "danger"
|
||||
})) {
|
||||
if (
|
||||
await confirmDialog({
|
||||
text: STRING_SIGN_OUT_CONFIRMATION,
|
||||
confirmButtonStyle: 'danger',
|
||||
})
|
||||
) {
|
||||
await this.application.signOut();
|
||||
this.dismiss();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** @template */
|
||||
@@ -133,7 +134,7 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
|
||||
onForgotPasscodeClick() {
|
||||
this.setState({
|
||||
forgotPasscode: true
|
||||
forgotPasscode: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,15 +144,22 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
this.setState({ values });
|
||||
}
|
||||
|
||||
onValueChange(prompt: ChallengePrompt, value: number) {
|
||||
const values = this.state.values;
|
||||
values[prompt.id]!.invalid = false;
|
||||
values[prompt.id]!.value = value;
|
||||
}
|
||||
|
||||
validate() {
|
||||
const failed = [];
|
||||
for (const prompt of this.getState().prompts) {
|
||||
const value = this.getState().values[prompt.id];
|
||||
if (!value || value.value.length === 0) {
|
||||
this.getState().values[prompt.id]!.invalid = true;
|
||||
let failed = 0;
|
||||
for (const prompt of this.state.prompts) {
|
||||
const value = this.state.values[prompt.id]!;
|
||||
if (typeof value.value === 'string' && value.value.length === 0) {
|
||||
this.state.values[prompt.id]!.invalid = true;
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
return failed.length === 0;
|
||||
return failed === 0;
|
||||
}
|
||||
|
||||
async submit() {
|
||||
@@ -161,15 +169,15 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
await this.setState({ processing: true });
|
||||
const values: ChallengeValue[] = [];
|
||||
for (const inputValue of Object.values(this.getState().values)) {
|
||||
const rawValue = inputValue!!.value;
|
||||
const rawValue = inputValue!.value;
|
||||
const value = new ChallengeValue(inputValue!.prompt, rawValue);
|
||||
values.push(value);
|
||||
}
|
||||
const processingPrompts = values.map((v) => v.prompt);
|
||||
await this.setState({
|
||||
processingPrompts: processingPrompts,
|
||||
processing: processingPrompts.length > 0
|
||||
})
|
||||
processing: processingPrompts.length > 0,
|
||||
});
|
||||
/**
|
||||
* Unfortunately neccessary to wait 50ms so that the above setState call completely
|
||||
* updates the UI to change processing state, before we enter into UI blocking operation
|
||||
@@ -181,7 +189,7 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
||||
} else {
|
||||
this.setState({ processing: false });
|
||||
}
|
||||
}, 50)
|
||||
}, 50);
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
@@ -202,7 +210,7 @@ export class ChallengeModal extends WebDirective {
|
||||
this.bindToController = true;
|
||||
this.scope = {
|
||||
challenge: '=',
|
||||
application: '='
|
||||
application: '=',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
isPayloadSourceRetrieved,
|
||||
isPayloadSourceInternalChange,
|
||||
ContentType,
|
||||
ProtectedAction,
|
||||
SNComponent,
|
||||
SNNote,
|
||||
SNTag,
|
||||
@@ -24,7 +23,7 @@ import { isDesktopApplication } from '@/utils';
|
||||
import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager';
|
||||
import template from './editor-view.pug';
|
||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||
import { AppStateEvent, EventSource } from '@/ui_models/app_state';
|
||||
import { EventSource } from '@/ui_models/app_state';
|
||||
import {
|
||||
STRING_DELETED_NOTE,
|
||||
STRING_INVALID_NOTE,
|
||||
@@ -85,7 +84,7 @@ type EditorState = {
|
||||
* then re-initialized. Used when reloading spellcheck status. */
|
||||
textareaUnloading: boolean
|
||||
/** Fields that can be directly mutated by the template */
|
||||
mutable: {}
|
||||
mutable: any
|
||||
}
|
||||
|
||||
type EditorValues = {
|
||||
@@ -98,7 +97,7 @@ function sortAlphabetically(array: SNComponent[]): SNComponent[] {
|
||||
return array.sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1);
|
||||
}
|
||||
|
||||
class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
||||
class EditorViewCtrl extends PureViewCtrl<unknown, EditorState> {
|
||||
/** Passed through template */
|
||||
readonly application!: WebApplication
|
||||
readonly editor!: Editor
|
||||
@@ -248,7 +247,7 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
||||
case ApplicationEvent.HighLatencySync:
|
||||
this.setState({ syncTakingTooLong: true });
|
||||
break;
|
||||
case ApplicationEvent.CompletedFullSync:
|
||||
case ApplicationEvent.CompletedFullSync: {
|
||||
this.setState({ syncTakingTooLong: false });
|
||||
const isInErrorState = this.state.saveError;
|
||||
/** if we're still dirty, don't change status, a sync is likely upcoming. */
|
||||
@@ -256,6 +255,7 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
||||
this.showAllChangesSavedStatus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ApplicationEvent.FailedSync:
|
||||
/**
|
||||
* Only show error status in editor if the note is dirty.
|
||||
@@ -601,10 +601,12 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
||||
this.setMenuState('showOptionsMenu', false);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
onTitleFocus() {
|
||||
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
onTitleBlur() {
|
||||
|
||||
}
|
||||
@@ -627,50 +629,35 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const run = async () => {
|
||||
if (this.note.locked) {
|
||||
this.application.alertService!.alert(
|
||||
STRING_DELETE_LOCKED_ATTEMPT
|
||||
);
|
||||
return;
|
||||
}
|
||||
const title = this.note.safeTitle().length
|
||||
? `'${this.note.title}'`
|
||||
: "this note";
|
||||
const text = StringDeleteNote(
|
||||
title,
|
||||
permanently
|
||||
if (this.note.locked) {
|
||||
this.application.alertService!.alert(
|
||||
STRING_DELETE_LOCKED_ATTEMPT
|
||||
);
|
||||
if (await confirmDialog({
|
||||
text,
|
||||
confirmButtonStyle: 'danger'
|
||||
})) {
|
||||
if (permanently) {
|
||||
this.performNoteDeletion(this.note);
|
||||
} else {
|
||||
this.saveNote(
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
(mutator) => {
|
||||
mutator.trashed = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
const requiresPrivilege = await this.application.privilegesService!.actionRequiresPrivilege(
|
||||
ProtectedAction.DeleteNote
|
||||
return;
|
||||
}
|
||||
const title = this.note.safeTitle().length
|
||||
? `'${this.note.title}'`
|
||||
: "this note";
|
||||
const text = StringDeleteNote(
|
||||
title,
|
||||
permanently
|
||||
);
|
||||
if (requiresPrivilege) {
|
||||
this.application.presentPrivilegesModal(
|
||||
ProtectedAction.DeleteNote,
|
||||
() => {
|
||||
run();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
run();
|
||||
if (await confirmDialog({
|
||||
text,
|
||||
confirmButtonStyle: 'danger'
|
||||
})) {
|
||||
if (permanently) {
|
||||
this.performNoteDeletion(this.note);
|
||||
} else {
|
||||
this.saveNote(
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
(mutator) => {
|
||||
mutator.trashed = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import { dateToLocalizedString, preventRefreshing } from '@/utils';
|
||||
import {
|
||||
ApplicationEvent,
|
||||
SyncQueueStrategy,
|
||||
ProtectedAction,
|
||||
ContentType,
|
||||
SNComponent,
|
||||
SNTheme,
|
||||
@@ -44,7 +43,7 @@ type DockShortcut = {
|
||||
}
|
||||
}
|
||||
|
||||
class FooterViewCtrl extends PureViewCtrl<{}, {
|
||||
class FooterViewCtrl extends PureViewCtrl<unknown, {
|
||||
outOfSync: boolean;
|
||||
hasPasscode: boolean;
|
||||
dataUpgradeAvailable: boolean;
|
||||
@@ -207,7 +206,7 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
||||
case AppStateEvent.BeganBackupDownload:
|
||||
statusService.setMessage("Saving local backup…");
|
||||
break;
|
||||
case AppStateEvent.EndedBackupDownload:
|
||||
case AppStateEvent.EndedBackupDownload: {
|
||||
const successMessage = "Successfully saved backup.";
|
||||
const errorMessage = "Unable to save local backup."
|
||||
statusService.setMessage(data.success ? successMessage : errorMessage);
|
||||
@@ -222,6 +221,7 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
||||
}
|
||||
}, twoSeconds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,28 +544,9 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
||||
}
|
||||
|
||||
async selectRoom(room: SNComponent) {
|
||||
const run = () => {
|
||||
this.$timeout(() => {
|
||||
this.roomShowState[room.uuid] = !this.roomShowState[room.uuid];
|
||||
});
|
||||
};
|
||||
|
||||
if (!this.roomShowState[room.uuid]) {
|
||||
const requiresPrivilege = await this.application.privilegesService!
|
||||
.actionRequiresPrivilege(
|
||||
ProtectedAction.ManageExtensions
|
||||
);
|
||||
if (requiresPrivilege) {
|
||||
this.application.presentPrivilegesModal(
|
||||
ProtectedAction.ManageExtensions,
|
||||
run
|
||||
);
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
this.$timeout(() => {
|
||||
this.roomShowState[room.uuid] = !this.roomShowState[room.uuid];
|
||||
});
|
||||
}
|
||||
|
||||
displayBetaDialog() {
|
||||
|
||||
Reference in New Issue
Block a user