Merge branch 'main' into develop
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
||||
MenuRow,
|
||||
PanelResizer,
|
||||
PasswordWizard,
|
||||
PermissionsModal,
|
||||
RevisionPreviewModal,
|
||||
HistoryMenu,
|
||||
SyncResolutionMenu,
|
||||
@@ -138,6 +139,7 @@ const startApplication: StartApplication = async function startApplication(
|
||||
.directive('menuRow', () => new MenuRow())
|
||||
.directive('panelResizer', () => new PanelResizer())
|
||||
.directive('passwordWizard', () => new PasswordWizard())
|
||||
.directive('permissionsModal', () => new PermissionsModal())
|
||||
.directive('revisionPreviewModal', () => new RevisionPreviewModal())
|
||||
.directive('historyMenu', () => new HistoryMenu())
|
||||
.directive('syncResolutionMenu', () => new SyncResolutionMenu())
|
||||
|
||||
@@ -7,6 +7,7 @@ export { InputModal } from './inputModal';
|
||||
export { MenuRow } from './menuRow';
|
||||
export { PanelResizer } from './panelResizer';
|
||||
export { PasswordWizard } from './passwordWizard';
|
||||
export { PermissionsModal } from './permissionsModal';
|
||||
export { RevisionPreviewModal } from './revisionPreviewModal';
|
||||
export { HistoryMenu } from './historyMenu';
|
||||
export { SyncResolutionMenu } from './syncResolutionMenu';
|
||||
|
||||
47
app/assets/javascripts/directives/views/permissionsModal.ts
Normal file
47
app/assets/javascripts/directives/views/permissionsModal.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { WebDirective } from './../../types';
|
||||
import template from '%/directives/permissions-modal.pug';
|
||||
|
||||
class PermissionsModalCtrl {
|
||||
|
||||
$element: JQLite
|
||||
callback!: (success: boolean) => void
|
||||
|
||||
/* @ngInject */
|
||||
constructor($element: JQLite) {
|
||||
this.$element = $element;
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
const elem = this.$element;
|
||||
const scope = elem.scope();
|
||||
scope.$destroy();
|
||||
elem.remove();
|
||||
}
|
||||
|
||||
accept() {
|
||||
this.callback(true);
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
deny() {
|
||||
this.callback(false);
|
||||
this.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
export class PermissionsModal extends WebDirective {
|
||||
constructor() {
|
||||
super();
|
||||
this.restrict = 'E';
|
||||
this.template = template;
|
||||
this.controller = PermissionsModalCtrl;
|
||||
this.controllerAs = 'ctrl';
|
||||
this.bindToController = true;
|
||||
this.scope = {
|
||||
show: '=',
|
||||
component: '=',
|
||||
permissionsString: '=',
|
||||
callback: '='
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -7,25 +7,21 @@ import {
|
||||
PayloadContent,
|
||||
} from '@standardnotes/snjs';
|
||||
|
||||
function sanitizeFileName(name: string) {
|
||||
return name
|
||||
.replace(/\//g, '')
|
||||
.replace(/\\+/g, '')
|
||||
.replace(/:/g, ' ')
|
||||
.replace(/\|/g, ' ')
|
||||
.replace(/\./g, ' ');
|
||||
}
|
||||
|
||||
function zippableTxtName(name: string, suffix = ''): string {
|
||||
const sanitizedName = sanitizeFileName(name);
|
||||
const nameEnd = suffix + '.txt';
|
||||
function zippableTxtName(name: string, suffix = ""): string {
|
||||
const sanitizedName = name
|
||||
.replace(/\//g, '')
|
||||
.replace(/\\+/g, '')
|
||||
.replace(/:/g, ' ')
|
||||
.replace(/\./g, ' ');
|
||||
const nameEnd = suffix + ".txt";
|
||||
const maxFileNameLength = 255;
|
||||
return sanitizedName.slice(0, maxFileNameLength - nameEnd.length) + nameEnd;
|
||||
}
|
||||
|
||||
export class ArchiveManager {
|
||||
private readonly application: WebApplication;
|
||||
private textFile?: string;
|
||||
|
||||
private readonly application: WebApplication
|
||||
private textFile?: string
|
||||
|
||||
constructor(application: WebApplication) {
|
||||
this.application = application;
|
||||
@@ -40,9 +36,10 @@ export class ArchiveManager {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
const blobData = new Blob([JSON.stringify(data, null, 2)], {
|
||||
type: 'text/json',
|
||||
});
|
||||
const blobData = new Blob(
|
||||
[JSON.stringify(data, null, 2)],
|
||||
{ type: 'text/json' }
|
||||
);
|
||||
if (encrypted) {
|
||||
this.downloadData(
|
||||
blobData,
|
||||
@@ -88,18 +85,21 @@ export class ArchiveManager {
|
||||
});
|
||||
}
|
||||
|
||||
private async downloadZippedDecryptedItems(data: BackupFile) {
|
||||
private async downloadZippedDecryptedItems(
|
||||
data: BackupFile
|
||||
) {
|
||||
await this.loadZip();
|
||||
const items = data.items;
|
||||
this.zip.createWriter(
|
||||
new this.zip.BlobWriter('application/zip'),
|
||||
async (zipWriter: any) => {
|
||||
await new Promise((resolve) => {
|
||||
const blob = new Blob([JSON.stringify(data, null, 2)], {
|
||||
type: 'text/plain',
|
||||
});
|
||||
const blob = new Blob(
|
||||
[JSON.stringify(data, null, 2)],
|
||||
{ type: 'text/plain' }
|
||||
);
|
||||
const fileName = zippableTxtName(
|
||||
'Standard Notes Backup and Import File'
|
||||
'Standard Notes Backup and Import File.txt'
|
||||
);
|
||||
zipWriter.add(fileName, new this.zip.BlobReader(blob), resolve);
|
||||
});
|
||||
@@ -120,8 +120,7 @@ export class ArchiveManager {
|
||||
name = '';
|
||||
}
|
||||
const blob = new Blob([contents], { type: 'text/plain' });
|
||||
const fileName =
|
||||
`Items/${sanitizeFileName(item.content_type)}/` +
|
||||
const fileName = `Items/${item.content_type}/` +
|
||||
zippableTxtName(name, `-${item.uuid.split('-')[0]}`);
|
||||
zipWriter.add(fileName, new this.zip.BlobReader(blob), () => {
|
||||
index++;
|
||||
@@ -139,9 +138,7 @@ export class ArchiveManager {
|
||||
});
|
||||
};
|
||||
nextFile();
|
||||
},
|
||||
onerror
|
||||
);
|
||||
}, onerror);
|
||||
}
|
||||
|
||||
private hrefForData(data: Blob) {
|
||||
|
||||
26
app/assets/templates/directives/permissions-modal.pug
Normal file
26
app/assets/templates/directives/permissions-modal.pug
Normal file
@@ -0,0 +1,26 @@
|
||||
.sk-modal-background(ng-click='ctrl.deny()')
|
||||
#permissions-modal.sk-modal-content
|
||||
.sn-component
|
||||
.sk-panel
|
||||
.sk-panel-header
|
||||
.sk-panel-header-title Activate Extension
|
||||
a.sk-a.info.close-button(ng-click='ctrl.deny()') Cancel
|
||||
.sk-panel-content
|
||||
.sk-panel-section
|
||||
.sk-panel-row
|
||||
.sk-h2
|
||||
strong {{ctrl.component.name}}
|
||||
| would like to interact with your
|
||||
| {{ctrl.permissionsString}}
|
||||
.sk-panel-row
|
||||
p.sk-p
|
||||
| Extensions use an offline messaging system to communicate. Learn more at
|
||||
a.sk-a.info(
|
||||
href='https://standardnotes.org/permissions',
|
||||
rel='noopener',
|
||||
target='_blank'
|
||||
) https://standardnotes.org/permissions.
|
||||
.sk-panel-footer
|
||||
button.sn-button.info.block.w-full.text-base.py-3(
|
||||
ng-click='ctrl.accept()'
|
||||
) Continue
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "standard-notes-web",
|
||||
"version": "3.6.3",
|
||||
"version": "3.6.4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user