fix: sync image - add mimeType, add manual sync in options-ui
This commit is contained in:
parent
2863a878e6
commit
50b27e731e
@ -17,8 +17,6 @@
|
|||||||
import { BrowserStorage } from '@pinmenote/browser-api';
|
import { BrowserStorage } from '@pinmenote/browser-api';
|
||||||
import { ICommand } from '../../../model/shared/common.dto';
|
import { ICommand } from '../../../model/shared/common.dto';
|
||||||
import { ObjectStoreKeys } from '../../../keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../keys/object.store.keys';
|
||||||
import { SegmentData } from '@pinmenote/page-compute';
|
|
||||||
import { fnConsoleLog } from '../../../fn/fn-console';
|
|
||||||
|
|
||||||
export class PageSegmentAddRefCommand implements ICommand<Promise<boolean>> {
|
export class PageSegmentAddRefCommand implements ICommand<Promise<boolean>> {
|
||||||
constructor(private hash: string) {}
|
constructor(private hash: string) {}
|
||||||
|
@ -33,7 +33,7 @@ export class PageSegmentAddCommand<T> implements ICommand<Promise<void>> {
|
|||||||
const key = `${ObjectStoreKeys.CONTENT_HASH_COUNT}:${this.content.hash}`;
|
const key = `${ObjectStoreKeys.CONTENT_HASH_COUNT}:${this.content.hash}`;
|
||||||
let count = (await BrowserStorage.get<number | undefined>(key)) || 0;
|
let count = (await BrowserStorage.get<number | undefined>(key)) || 0;
|
||||||
count++;
|
count++;
|
||||||
fnConsoleLog('PageSegmentAddCommand->incrementCount', count);
|
// fnConsoleLog('PageSegmentAddCommand->incrementCount', count);
|
||||||
await BrowserStorage.set(key, count);
|
await BrowserStorage.set(key, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,8 @@ export enum BusMessageType {
|
|||||||
CONTENT_TAKE_SCREENSHOT = 'content.take.screenshot',
|
CONTENT_TAKE_SCREENSHOT = 'content.take.screenshot',
|
||||||
CONTENT_FETCH_PDF = 'content.fetch.pdf',
|
CONTENT_FETCH_PDF = 'content.fetch.pdf',
|
||||||
CONTENT_THEME = 'content.theme',
|
CONTENT_THEME = 'content.theme',
|
||||||
|
// Iframe
|
||||||
|
OPTIONS_SYNC_OUTGOING_OBJECT = 'options.sync.outgoing.object',
|
||||||
// Iframe content script
|
// Iframe content script
|
||||||
IFRAME_INDEX = 'iframe.index',
|
IFRAME_INDEX = 'iframe.index',
|
||||||
IFRAME_INDEX_REGISTER = 'iframe.index.register',
|
IFRAME_INDEX_REGISTER = 'iframe.index.register',
|
||||||
|
@ -48,9 +48,11 @@ export const AccountDetailsComponent: FunctionComponent<Props> = (props) => {
|
|||||||
|
|
||||||
if (PopupTokenStore.token) {
|
if (PopupTokenStore.token) {
|
||||||
setTokenData(jwtDecode<TokenDataDto>(PopupTokenStore.token.access_token));
|
setTokenData(jwtDecode<TokenDataDto>(PopupTokenStore.token.access_token));
|
||||||
quotaKey = dispatcher.addListener<ServerQuotaResponse>(
|
quotaKey = dispatcher.addListener<ServerQuotaResponse | ServerErrorDto>(
|
||||||
BusMessageType.POPUP_SERVER_QUOTA,
|
BusMessageType.POPUP_SERVER_QUOTA,
|
||||||
(event, key, value) => {
|
(event, key, value) => {
|
||||||
|
// TODO fix server error handling
|
||||||
|
if ('code' in value) return;
|
||||||
LogManager.log(`${event} - ${JSON.stringify(value)}`);
|
LogManager.log(`${event} - ${JSON.stringify(value)}`);
|
||||||
setServerQuota(value);
|
setServerQuota(value);
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension).
|
||||||
|
* Copyright (c) 2023 Michal Szczepanski.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import React, { FunctionComponent, useEffect, useRef } from 'react';
|
||||||
|
import { BrowserApi } from '@pinmenote/browser-api';
|
||||||
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import DownloadIcon from '@mui/icons-material/Download';
|
||||||
|
import ClearIcon from '@mui/icons-material/Clear';
|
||||||
|
import { ObjDto } from '../../../common/model/obj/obj.dto';
|
||||||
|
import { ObjPageDto } from '../../../common/model/obj/obj-page.dto';
|
||||||
|
import { PageSnapshotDto } from '../../../common/model/obj/page-snapshot.dto';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { DATE_YEAR_SECOND } from '../../../common/date-format.constraints';
|
||||||
|
import CloudSyncIcon from '@mui/icons-material/CloudSync';
|
||||||
|
import { BusMessageType } from '../../../common/model/bus.model';
|
||||||
|
import { TinyDispatcher } from '@pinmenote/tiny-dispatcher';
|
||||||
|
import { SyncObjectStatus } from '../../../common/model/sync.model';
|
||||||
|
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
obj?: ObjDto<ObjPageDto>;
|
||||||
|
isLoading: boolean;
|
||||||
|
handleDownload: () => void;
|
||||||
|
handleClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HtmlPreviewHeaderComponent: FunctionComponent<Props> = (props) => {
|
||||||
|
const titleRef = useRef<HTMLHeadingElement>(null);
|
||||||
|
const urlRef = useRef<HTMLDivElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!titleRef.current) return;
|
||||||
|
if (!urlRef.current) return;
|
||||||
|
if (props.obj) renderHeader(props.obj);
|
||||||
|
const dispatcher = TinyDispatcher.getInstance();
|
||||||
|
const syncKey = dispatcher.addListener<SyncObjectStatus>(
|
||||||
|
BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT,
|
||||||
|
(event, key, value) => {
|
||||||
|
fnConsoleLog('HtmlPreviewHeaderComponent->SYNC !!!!!!!', event, key, value);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
dispatcher.removeListener(BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT, syncKey);
|
||||||
|
};
|
||||||
|
}, [props]);
|
||||||
|
|
||||||
|
const renderHeader = (obj: ObjDto<ObjPageDto>): void => {
|
||||||
|
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
||||||
|
if (titleRef.current) {
|
||||||
|
titleRef.current.innerHTML = snapshot.info.title;
|
||||||
|
}
|
||||||
|
if (urlRef.current) {
|
||||||
|
urlRef.current.innerHTML = `
|
||||||
|
<a href="${snapshot.info.url.href}" target="_blank" style="word-break: break-all">
|
||||||
|
${snapshot.info.url.href}
|
||||||
|
</a><span style="margin-left: 10px;">Created At : ${dayjs(obj.createdAt).format(DATE_YEAR_SECOND)}</span>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleManualSync = async () => {
|
||||||
|
await BrowserApi.sendRuntimeMessage({ type: BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT, data: props.obj?.id });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ backgroundColor: '#ffffff', width: '100%', display: 'flex', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ marginLeft: '10px', marginBottom: '5px' }}>
|
||||||
|
<h2 style={{ marginTop: '5px', marginBottom: '5px' }} ref={titleRef}></h2>
|
||||||
|
<div ref={urlRef}></div>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<div style={{ display: props.isLoading ? 'flex' : 'none' }}>
|
||||||
|
<CircularProgress />
|
||||||
|
</div>
|
||||||
|
<IconButton onClick={handleManualSync}>
|
||||||
|
<CloudSyncIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={props.handleDownload}>
|
||||||
|
<DownloadIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={props.handleClose}>
|
||||||
|
<ClearIcon />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -19,10 +19,6 @@ import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
|||||||
import { SegmentImg, SegmentPage, SegmentType } from '@pinmenote/page-compute';
|
import { SegmentImg, SegmentPage, SegmentType } from '@pinmenote/page-compute';
|
||||||
import { BrowserApi } from '@pinmenote/browser-api';
|
import { BrowserApi } from '@pinmenote/browser-api';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import ClearIcon from '@mui/icons-material/Clear';
|
|
||||||
import { DATE_YEAR_SECOND } from '../../../common/date-format.constraints';
|
|
||||||
import DownloadIcon from '@mui/icons-material/Download';
|
|
||||||
import IconButton from '@mui/material/IconButton';
|
|
||||||
import { IframeHtmlFactory } from '../../../common/factory/iframe-html.factory';
|
import { IframeHtmlFactory } from '../../../common/factory/iframe-html.factory';
|
||||||
import { LinkHrefStore } from '../../../common/store/link-href.store';
|
import { LinkHrefStore } from '../../../common/store/link-href.store';
|
||||||
import { ObjGetCommand } from '../../../common/command/obj/obj-get.command';
|
import { ObjGetCommand } from '../../../common/command/obj/obj-get.command';
|
||||||
@ -33,10 +29,10 @@ import { PageSnapshotDto } from '../../../common/model/obj/page-snapshot.dto';
|
|||||||
import { PinComponent } from '../../../common/components/pin/pin.component';
|
import { PinComponent } from '../../../common/components/pin/pin.component';
|
||||||
import { SettingsStore } from '../../store/settings.store';
|
import { SettingsStore } from '../../store/settings.store';
|
||||||
import { XpathFactory } from '../../../common/factory/xpath.factory';
|
import { XpathFactory } from '../../../common/factory/xpath.factory';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||||
import { fnSleep } from '../../../common/fn/fn-sleep';
|
import { fnSleep } from '../../../common/fn/fn-sleep';
|
||||||
import { fnUid } from '../../../common/fn/fn-uid';
|
import { fnUid } from '../../../common/fn/fn-uid';
|
||||||
|
import { HtmlPreviewHeaderComponent } from './html-preview-header.component';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
@ -45,13 +41,11 @@ interface Props {
|
|||||||
export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const htmlRef = useRef<HTMLDivElement>(null);
|
const htmlRef = useRef<HTMLDivElement>(null);
|
||||||
const titleRef = useRef<HTMLHeadingElement>(null);
|
|
||||||
const urlRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const [visible, setVisible] = useState<boolean>(props.visible);
|
const [visible, setVisible] = useState<boolean>(props.visible);
|
||||||
|
|
||||||
const [pageSegment, setPageSegment] = useState<SegmentPage | undefined>();
|
const [pageSegment, setPageSegment] = useState<SegmentPage | undefined>();
|
||||||
const [pageSnapshot, setPageSnapshot] = useState<PageSnapshotDto | undefined>();
|
const [objData, setObjData] = useState<ObjDto<ObjPageDto> | undefined>();
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const [isPreLoading, setIsPreLoading] = useState<boolean>(true);
|
const [isPreLoading, setIsPreLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
@ -62,21 +56,18 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
if (!idhash[0].startsWith('#obj')) return;
|
if (!idhash[0].startsWith('#obj')) return;
|
||||||
try {
|
try {
|
||||||
fnConsoleLog('HtmlPreviewComponent->useEffect->render', props.visible, visible);
|
fnConsoleLog('HtmlPreviewComponent->useEffect->render', props.visible, visible);
|
||||||
render(parseInt(idhash[1]));
|
render(parseInt(idhash[1])).catch((e) => fnConsoleLog('HtmlPreviewComponent->useEffect->render->ERROR', e));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
fnConsoleLog('Error render or parseInt', e);
|
fnConsoleLog('Error render or parseInt', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, [props]);
|
||||||
|
|
||||||
const render = (id: number) => {
|
const render = async (id: number) => {
|
||||||
if (titleRef.current) titleRef.current.innerHTML = '';
|
|
||||||
if (urlRef.current) urlRef.current.innerHTML = '';
|
|
||||||
setTimeout(async () => {
|
|
||||||
setIsPreLoading(true);
|
setIsPreLoading(true);
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const obj = await new ObjGetCommand<ObjPageDto>(id).execute();
|
const obj = await new ObjGetCommand<ObjPageDto>(id).execute();
|
||||||
setPageSnapshot(obj.data.snapshot);
|
setObjData(obj);
|
||||||
const pageSegment = await new PageSegmentGetCommand<SegmentPage>(obj.data.snapshot.segment).execute();
|
const pageSegment = await new PageSegmentGetCommand<SegmentPage>(obj.data.snapshot.segment).execute();
|
||||||
if (pageSegment) {
|
if (pageSegment) {
|
||||||
setPageSegment(pageSegment.content);
|
setPageSegment(pageSegment.content);
|
||||||
@ -92,7 +83,6 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
const pinIds = await LinkHrefStore.pinIds(obj.data.snapshot.info.url.href);
|
const pinIds = await LinkHrefStore.pinIds(obj.data.snapshot.info.url.href);
|
||||||
await renderPins(pinIds);
|
await renderPins(pinIds);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderPins = async (ids: number[]) => {
|
const renderPins = async (ids: number[]) => {
|
||||||
@ -160,8 +150,6 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
|
|
||||||
const renderCanvas = (obj: ObjDto<ObjPageDto>, content?: SegmentPage) => {
|
const renderCanvas = (obj: ObjDto<ObjPageDto>, content?: SegmentPage) => {
|
||||||
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
||||||
renderHeader(obj);
|
|
||||||
|
|
||||||
if (!htmlRef.current) return;
|
if (!htmlRef.current) return;
|
||||||
if (!containerRef.current) return;
|
if (!containerRef.current) return;
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
@ -187,7 +175,6 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
|
|
||||||
const renderSnapshot = async (obj: ObjDto<ObjPageDto>, segment?: SegmentPage): Promise<void> => {
|
const renderSnapshot = async (obj: ObjDto<ObjPageDto>, segment?: SegmentPage): Promise<void> => {
|
||||||
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
||||||
renderHeader(obj);
|
|
||||||
if (!htmlRef.current) return;
|
if (!htmlRef.current) return;
|
||||||
if (!containerRef.current) return;
|
if (!containerRef.current) return;
|
||||||
if (!segment) return;
|
if (!segment) return;
|
||||||
@ -210,19 +197,6 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderHeader = (obj: ObjDto<ObjPageDto>): void => {
|
|
||||||
const snapshot: PageSnapshotDto = obj.data.snapshot;
|
|
||||||
if (titleRef.current) {
|
|
||||||
titleRef.current.innerHTML = snapshot.info.title;
|
|
||||||
}
|
|
||||||
if (urlRef.current) {
|
|
||||||
urlRef.current.innerHTML = `
|
|
||||||
<a href="${snapshot.info.url.href}" target="_blank" style="word-break: break-all">
|
|
||||||
${snapshot.info.url.href}
|
|
||||||
</a><span style="margin-left: 10px;">Created At : ${dayjs(obj.createdAt).format(DATE_YEAR_SECOND)}</span>`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const writeDoc = async (doc: Document, html: string, assets: string[], cleanLoader = false): Promise<void> => {
|
const writeDoc = async (doc: Document, html: string, assets: string[], cleanLoader = false): Promise<void> => {
|
||||||
doc.write(html);
|
doc.write(html);
|
||||||
doc.close();
|
doc.close();
|
||||||
@ -310,7 +284,7 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDownload = async () => {
|
const handleDownload = async () => {
|
||||||
if (!pageSegment || !pageSnapshot) return;
|
if (!pageSegment || !objData) return;
|
||||||
if (!htmlRef.current) return;
|
if (!htmlRef.current) return;
|
||||||
const iframe = htmlRef.current.lastChild as HTMLIFrameElement;
|
const iframe = htmlRef.current.lastChild as HTMLIFrameElement;
|
||||||
// TODO gather all iframe hashes and pass here with content
|
// TODO gather all iframe hashes and pass here with content
|
||||||
@ -347,23 +321,12 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
|||||||
left: '0px'
|
left: '0px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ backgroundColor: '#ffffff', width: '100%', display: 'flex', justifyContent: 'space-between' }}>
|
<HtmlPreviewHeaderComponent
|
||||||
<div style={{ marginLeft: '10px', marginBottom: '5px' }}>
|
obj={objData}
|
||||||
<h2 style={{ marginTop: '5px', marginBottom: '5px' }} ref={titleRef}></h2>
|
handleDownload={handleDownload}
|
||||||
<div ref={urlRef}></div>
|
handleClose={handleClose}
|
||||||
</div>
|
isLoading={isLoading}
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
/>
|
||||||
<div style={{ display: isLoading ? 'flex' : 'none' }}>
|
|
||||||
<CircularProgress />
|
|
||||||
</div>
|
|
||||||
<IconButton onClick={handleDownload}>
|
|
||||||
<DownloadIcon />
|
|
||||||
</IconButton>
|
|
||||||
<IconButton onClick={handleClose}>
|
|
||||||
<ClearIcon />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ width: '100%', height: '100%', backgroundColor: '#ffffff' }} ref={htmlRef}>
|
<div style={{ width: '100%', height: '100%', backgroundColor: '#ffffff' }} ref={htmlRef}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -36,7 +36,6 @@ export class ApiStoreCommitCommand extends ApiCallBase implements ICommand<Promi
|
|||||||
},
|
},
|
||||||
this.refreshParams()
|
this.refreshParams()
|
||||||
);
|
);
|
||||||
fnConsoleLog('ApiStoreCommitCommand->response', resp);
|
|
||||||
return resp.ok;
|
return resp.ok;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
fnConsoleLog('ApiStoreBeginCommand->Error', e);
|
fnConsoleLog('ApiStoreBeginCommand->Error', e);
|
||||||
|
@ -58,8 +58,9 @@ export enum SyncHashType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SegmentSingleHash {
|
export interface SegmentSingleHash {
|
||||||
hash: string;
|
|
||||||
type: SyncHashType;
|
type: SyncHashType;
|
||||||
|
hash: string;
|
||||||
|
mimeType?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SegmentHashListResponse {
|
export interface SegmentHashListResponse {
|
||||||
|
@ -16,27 +16,36 @@
|
|||||||
*/
|
*/
|
||||||
import { ApiCallBase } from '../../api-call.base';
|
import { ApiCallBase } from '../../api-call.base';
|
||||||
import { FetchService } from '@pinmenote/fetch-service';
|
import { FetchService } from '@pinmenote/fetch-service';
|
||||||
import { ICommand } from '../../../../../common/model/shared/common.dto';
|
import { ICommand, ServerErrorDto } from '../../../../../common/model/shared/common.dto';
|
||||||
import { fnConsoleLog } from '../../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../../common/fn/fn-console';
|
||||||
import { ObjChangesResponse } from '../api-store.model';
|
import { ObjChangesResponse } from '../api-store.model';
|
||||||
|
import { ApiErrorCode } from '../../../../../common/model/shared/api.error-code';
|
||||||
|
|
||||||
export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand<Promise<ObjChangesResponse | undefined>> {
|
const errorResponse: ServerErrorDto = { code: ApiErrorCode.INTERNAL, message: 'Send request problem' };
|
||||||
constructor(private serverId?: number) {
|
|
||||||
|
export class ApiObjGetChangesCommand
|
||||||
|
extends ApiCallBase
|
||||||
|
implements ICommand<Promise<ObjChangesResponse | ServerErrorDto>>
|
||||||
|
{
|
||||||
|
constructor(private serverId: number) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
async execute(): Promise<ObjChangesResponse | undefined> {
|
async execute(): Promise<ObjChangesResponse | ServerErrorDto> {
|
||||||
await this.initTokenData();
|
await this.initTokenData();
|
||||||
if (!this.storeUrl) return;
|
if (!this.storeUrl) return errorResponse;
|
||||||
try {
|
try {
|
||||||
const resp = await FetchService.fetch<ObjChangesResponse>(
|
const resp = await FetchService.fetch<ObjChangesResponse | ServerErrorDto>(
|
||||||
`${this.storeUrl}/api/v1/obj/changes?serverId=${this.serverId || 0}`,
|
`${this.storeUrl}/api/v1/obj/changes?serverId=${this.serverId}`,
|
||||||
{ headers: this.getAuthHeaders() },
|
{ headers: this.getAuthHeaders() },
|
||||||
this.refreshParams()
|
this.refreshParams()
|
||||||
);
|
);
|
||||||
fnConsoleLog('ApiStoreChangesCommand->response', resp);
|
if (resp.status === 200) return resp.data;
|
||||||
return resp.data;
|
fnConsoleLog(resp);
|
||||||
|
errorResponse.message = (resp.data as ServerErrorDto).message;
|
||||||
|
return errorResponse;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
fnConsoleLog('ApiStoreChangesCommand->Error', e);
|
fnConsoleLog('ApiObjGetChangesCommand->Error', e);
|
||||||
}
|
}
|
||||||
|
return errorResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,15 +36,16 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand<Promis
|
|||||||
async execute(): Promise<boolean> {
|
async execute(): Promise<boolean> {
|
||||||
await this.initTokenData();
|
await this.initTokenData();
|
||||||
if (!this.storeUrl) return false;
|
if (!this.storeUrl) return false;
|
||||||
if (await this.hasSegment()) return true;
|
// if (await this.hasSegment(this.storeUrl)) return true;
|
||||||
return await this.addSegment();
|
return await this.addSegment(this.storeUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
async hasSegment(): Promise<boolean> {
|
async hasSegment(storeUrl: string): Promise<boolean> {
|
||||||
|
if (!this.storeUrl) return false;
|
||||||
const authHeaders = this.getAuthHeaders();
|
const authHeaders = this.getAuthHeaders();
|
||||||
const params = this.data.parent ? `?parent=${this.data.parent}` : '';
|
const params = this.data.parent ? `?parent=${this.data.parent}` : '';
|
||||||
const resp = await FetchService.fetch<BeginTxResponse>(
|
const resp = await FetchService.fetch<BeginTxResponse>(
|
||||||
`${this.storeUrl!}/api/v1/segment/has/${this.tx.tx}/${this.data.hash}${params}`,
|
`${storeUrl}/api/v1/segment/has/${this.tx.tx}/${this.data.hash}${params}`,
|
||||||
{
|
{
|
||||||
type: 'TEXT',
|
type: 'TEXT',
|
||||||
headers: {
|
headers: {
|
||||||
@ -56,22 +57,26 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand<Promis
|
|||||||
return resp.status === 200;
|
return resp.status === 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addSegment(): Promise<boolean> {
|
async addSegment(storeUrl: string): Promise<boolean> {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
if (this.data.type.toString() === SyncHashType.Img) {
|
if (this.data.type.toString() === SyncHashType.Img) {
|
||||||
if (this.file === 'data:') {
|
if (this.file === 'data:') {
|
||||||
fnConsoleLog('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', this.file);
|
fnConsoleLog('ApiSegmentAddCommand->addSegment->EMPTY', this.file);
|
||||||
formData.append('file', new Blob([this.file], { type: 'image/svg+xml' }));
|
formData.append('file', new Blob([this.file], { type: 'image/svg+xml' }));
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
formData.append('file', fnB64toBlob(this.file));
|
const blob = fnB64toBlob(this.file);
|
||||||
|
formData.append('mimeType', blob.type);
|
||||||
|
formData.append('file', blob);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(this.file, this.data, e);
|
fnConsoleLog(this.file, this.data, e);
|
||||||
throw new Error('aaaaaaaaaaaaaaaaaaaaa');
|
throw new Error('ApiSegmentAddCommand->addSegment->Error->Img->base64');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.data.type.toString() === SyncHashType.ObjPdf) {
|
} else if (this.data.type.toString() === SyncHashType.ObjPdf) {
|
||||||
formData.append('file', fnB64toBlob(this.file));
|
const blob = fnB64toBlob(this.file);
|
||||||
|
formData.append('mimeType', blob.type);
|
||||||
|
formData.append('file', blob);
|
||||||
} else {
|
} else {
|
||||||
const fileData = deflate(this.file);
|
const fileData = deflate(this.file);
|
||||||
formData.append('file', new Blob([fileData], { type: 'application/zip' }));
|
formData.append('file', new Blob([fileData], { type: 'application/zip' }));
|
||||||
@ -85,7 +90,7 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand<Promis
|
|||||||
|
|
||||||
const authHeaders = this.getAuthHeaders(false);
|
const authHeaders = this.getAuthHeaders(false);
|
||||||
const resp = await FetchService.fetch(
|
const resp = await FetchService.fetch(
|
||||||
`${this.storeUrl!}/api/v1/segment/add/${this.tx.tx}`,
|
`${storeUrl}/api/v1/segment/add/${this.tx.tx}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...authHeaders
|
...authHeaders
|
||||||
|
@ -20,15 +20,16 @@ import { ICommand } from '../../../../../common/model/shared/common.dto';
|
|||||||
import { fnConsoleLog } from '../../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../../common/fn/fn-console';
|
||||||
|
|
||||||
export class ApiSegmentGetCommand extends ApiCallBase implements ICommand<Promise<Blob | undefined>> {
|
export class ApiSegmentGetCommand extends ApiCallBase implements ICommand<Promise<Blob | undefined>> {
|
||||||
constructor(private hash: string) {
|
constructor(private hash: string, private mimeType?: string) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
async execute(): Promise<Blob | undefined> {
|
async execute(): Promise<Blob | undefined> {
|
||||||
await this.initTokenData();
|
await this.initTokenData();
|
||||||
if (!this.storeUrl) return;
|
if (!this.storeUrl) return;
|
||||||
try {
|
try {
|
||||||
|
const mimeType = this.mimeType ? `?mimeType=${encodeURI(this.mimeType)}` : '';
|
||||||
const resp = await FetchService.fetch<Blob>(
|
const resp = await FetchService.fetch<Blob>(
|
||||||
`${this.storeUrl}/api/v1/segment/${this.hash}`,
|
`${this.storeUrl}/api/v1/segment/${this.hash}${mimeType}`,
|
||||||
{ headers: this.getAuthHeaders(), type: 'BLOB' },
|
{ headers: this.getAuthHeaders(), type: 'BLOB' },
|
||||||
this.refreshParams()
|
this.refreshParams()
|
||||||
);
|
);
|
||||||
|
@ -16,17 +16,24 @@
|
|||||||
*/
|
*/
|
||||||
import { ApiCallBase } from '../../api-call.base';
|
import { ApiCallBase } from '../../api-call.base';
|
||||||
import { FetchService } from '@pinmenote/fetch-service';
|
import { FetchService } from '@pinmenote/fetch-service';
|
||||||
import { ICommand } from '../../../../../common/model/shared/common.dto';
|
import { ICommand, ServerErrorDto } from '../../../../../common/model/shared/common.dto';
|
||||||
import { ServerQuotaResponse } from '../../../../../common/model/sync-server.model';
|
import { ServerQuotaResponse } from '../../../../../common/model/sync-server.model';
|
||||||
|
import { ApiErrorCode } from '../../../../../common/model/shared/api.error-code';
|
||||||
|
import { fnConsoleLog } from '../../../../../common/fn/fn-console';
|
||||||
|
|
||||||
export class ApiSegmentQuotaGetCommand extends ApiCallBase implements ICommand<Promise<ServerQuotaResponse>> {
|
export class ApiSegmentQuotaGetCommand
|
||||||
|
extends ApiCallBase
|
||||||
|
implements ICommand<Promise<ServerQuotaResponse | ServerErrorDto>>
|
||||||
|
{
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
async execute(): Promise<ServerQuotaResponse> {
|
async execute(): Promise<ServerQuotaResponse | ServerErrorDto> {
|
||||||
await this.initTokenData();
|
await this.initTokenData();
|
||||||
|
if (!this.storeUrl) return { code: ApiErrorCode.INTERNAL, message: 'ApiSegmentQuotaGetCommand' };
|
||||||
|
try {
|
||||||
const resp = await FetchService.fetch<ServerQuotaResponse>(
|
const resp = await FetchService.fetch<ServerQuotaResponse>(
|
||||||
`${this.storeUrl!}/api/v1/segment/quota`,
|
`${this.storeUrl}/api/v1/segment/quota`,
|
||||||
{
|
{
|
||||||
type: 'JSON',
|
type: 'JSON',
|
||||||
headers: this.getAuthHeaders(true)
|
headers: this.getAuthHeaders(true)
|
||||||
@ -34,5 +41,9 @@ export class ApiSegmentQuotaGetCommand extends ApiCallBase implements ICommand<P
|
|||||||
this.refreshParams()
|
this.refreshParams()
|
||||||
);
|
);
|
||||||
return resp.data;
|
return resp.data;
|
||||||
|
} catch (e) {
|
||||||
|
fnConsoleLog('ApiSegmentQuotaGetCommand', e);
|
||||||
|
}
|
||||||
|
return { code: ApiErrorCode.INTERNAL, message: 'ApiSegmentQuotaGetCommand' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,18 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import { ApiSegmentQuotaGetCommand, ServerQuotaResponse } from '../api/store/segment/api-segment-quota-get.command';
|
import { ApiSegmentQuotaGetCommand } from '../api/store/segment/api-segment-quota-get.command';
|
||||||
import { BrowserApi } from '@pinmenote/browser-api';
|
import { BrowserApi } from '@pinmenote/browser-api';
|
||||||
import { BusMessageType } from '../../../common/model/bus.model';
|
import { BusMessageType } from '../../../common/model/bus.model';
|
||||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
import { ICommand, ServerErrorDto } from '../../../common/model/shared/common.dto';
|
||||||
|
import { ServerQuotaResponse } from '../../../common/model/sync-server.model';
|
||||||
|
|
||||||
export class PopupServerQuotaCommand implements ICommand<Promise<void>> {
|
export class PopupServerQuotaCommand implements ICommand<Promise<void>> {
|
||||||
async execute(): Promise<void> {
|
async execute(): Promise<void> {
|
||||||
const data = await new ApiSegmentQuotaGetCommand().execute();
|
const data = await new ApiSegmentQuotaGetCommand().execute();
|
||||||
await BrowserApi.sendRuntimeMessage<ServerQuotaResponse>({ type: BusMessageType.POPUP_SERVER_QUOTA, data });
|
await BrowserApi.sendRuntimeMessage<ServerQuotaResponse | ServerErrorDto>({
|
||||||
|
type: BusMessageType.POPUP_SERVER_QUOTA,
|
||||||
|
data
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ export class SyncSnapshotIncomingCommand implements ICommand<Promise<boolean>> {
|
|||||||
if (!hashList) return false;
|
if (!hashList) return false;
|
||||||
const pageSnapshot = await this.getSnapshot(hashList);
|
const pageSnapshot = await this.getSnapshot(hashList);
|
||||||
if (!pageSnapshot) {
|
if (!pageSnapshot) {
|
||||||
fnConsoleLog('SyncSnapshotIncomingCommand->execute PROBLEM !!!!!!!!!!!!!!!!!!!', this.change);
|
fnConsoleLog('SyncSnapshotIncomingCommand->execute PROBLEM !!!!!!!!!!!!!!!!!!!', this.change, hashList);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// sleep 1s for now
|
// sleep 1s for now
|
||||||
@ -108,7 +108,7 @@ export class SyncSnapshotIncomingCommand implements ICommand<Promise<boolean>> {
|
|||||||
let info: PageSnapshotInfoDto | undefined;
|
let info: PageSnapshotInfoDto | undefined;
|
||||||
let segment: string | undefined = undefined;
|
let segment: string | undefined = undefined;
|
||||||
for (const child of hashList.children) {
|
for (const child of hashList.children) {
|
||||||
const segmentData = await new ApiSegmentGetCommand(child.hash).execute();
|
const segmentData = await new ApiSegmentGetCommand(child.hash, child.mimeType).execute();
|
||||||
if (!segmentData) continue;
|
if (!segmentData) continue;
|
||||||
switch (child.type.toString()) {
|
switch (child.type.toString()) {
|
||||||
case SyncHashType.Img: {
|
case SyncHashType.Img: {
|
||||||
@ -117,10 +117,13 @@ export class SyncSnapshotIncomingCommand implements ICommand<Promise<boolean>> {
|
|||||||
let src = 'data:';
|
let src = 'data:';
|
||||||
try {
|
try {
|
||||||
src = await UrlFactory.toDataUri(segmentData);
|
src = await UrlFactory.toDataUri(segmentData);
|
||||||
|
// @vane WORKAROUND FIX convert image/svg -> image/svg+xml to render correctly inside <img> tag
|
||||||
|
const check = 'data:image/svg';
|
||||||
|
if (src.startsWith(check)) src = 'data:image/svg+xml' + src.substring(check.length);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const buffer = await segmentData.arrayBuffer();
|
const buffer = await segmentData.arrayBuffer();
|
||||||
const textData = new TextDecoder().decode(buffer);
|
const textData = new TextDecoder().decode(buffer);
|
||||||
console.log('ERROR !!!!!!!!! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa !!!!!!!!!!!!!!!!!!!!!!!!!!!', textData);
|
fnConsoleLog('SyncSnapshotIncomingCommand->getSnapshot->Img->Error !!!', textData);
|
||||||
}
|
}
|
||||||
const content: SegmentImg = { src };
|
const content: SegmentImg = { src };
|
||||||
await new PageSegmentAddCommand({ type: SegmentType.IMG, hash: child.hash, content }).execute();
|
await new PageSegmentAddCommand({ type: SegmentType.IMG, hash: child.hash, content }).execute();
|
||||||
@ -162,7 +165,6 @@ export class SyncSnapshotIncomingCommand implements ICommand<Promise<boolean>> {
|
|||||||
segment = child.hash;
|
segment = child.hash;
|
||||||
const content = await this.getString(segmentData);
|
const content = await this.getString(segmentData);
|
||||||
const html: SegmentHtml = JSON.parse(content);
|
const html: SegmentHtml = JSON.parse(content);
|
||||||
fnConsoleLog('SyncSnapshotIncomingCommand->getSnapshot->PageSnapshotFirstHash', html, child.hash);
|
|
||||||
await new PageSegmentAddCommand({
|
await new PageSegmentAddCommand({
|
||||||
type: SegmentType.SNAPSHOT,
|
type: SegmentType.SNAPSHOT,
|
||||||
content: html,
|
content: html,
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension).
|
||||||
|
* Copyright (c) 2023 Michal Szczepanski.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import { BrowserApi } from '@pinmenote/browser-api';
|
||||||
|
import { ICommand } from '../../../../common/model/shared/common.dto';
|
||||||
|
import { ObjGetCommand } from '../../../../common/command/obj/obj-get.command';
|
||||||
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
|
import { BusMessageType } from '../../../../common/model/bus.model';
|
||||||
|
import { ObjDto, ObjRemovedDto, ObjTypeDto } from '../../../../common/model/obj/obj.dto';
|
||||||
|
import { SyncSnapshotCommand } from '../outgoing/sync-snapshot.command';
|
||||||
|
import { ObjPageDto } from '../../../../common/model/obj/obj-page.dto';
|
||||||
|
import { SyncPinCommand } from '../outgoing/sync-pin.command';
|
||||||
|
import { ObjPinDto } from '../../../../common/model/obj/obj-pin.dto';
|
||||||
|
import { SyncPdfCommand } from '../outgoing/sync-pdf.command';
|
||||||
|
import { ObjPdfDto } from '../../../../common/model/obj/obj-pdf.dto';
|
||||||
|
import { SyncNoteCommand } from '../outgoing/sync-note.command';
|
||||||
|
import { ObjNoteDto, ObjPageNoteDto } from '../../../../common/model/obj/obj-note.dto';
|
||||||
|
import { SyncPageNoteCommand } from '../outgoing/sync-page-note.command';
|
||||||
|
import { SyncRemovedCommand } from '../outgoing/sync-removed.command';
|
||||||
|
import { SyncTxHelper } from '../sync-tx.helper';
|
||||||
|
import { BeginTxResponse } from '../../api/store/api-store.model';
|
||||||
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
|
|
||||||
|
export class SyncManualOutgoingCommand implements ICommand<Promise<void>> {
|
||||||
|
constructor(private id: number) {}
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
fnConsoleLog('SyncManualOutgoingCommand !!!!!!!!!!');
|
||||||
|
const obj = await new ObjGetCommand(this.id).execute();
|
||||||
|
if (!obj) {
|
||||||
|
fnConsoleLog('SyncObjectCommand->syncObject EMPTY', this.id, obj);
|
||||||
|
await this.sendResponse(SyncObjectStatus.OBJECT_NOT_EXISTS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tx = await SyncTxHelper.begin();
|
||||||
|
if (!tx) {
|
||||||
|
fnConsoleLog('SyncManualOutgoingCommand !!!!!!!!!! TX', tx);
|
||||||
|
await this.sendResponse(SyncObjectStatus.TX_LOCKED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const status = await this.syncObj(obj, tx);
|
||||||
|
await this.sendResponse(status);
|
||||||
|
fnConsoleLog('SyncManualOutgoingCommand->execute id', obj.id, 'serverId', obj.server?.id);
|
||||||
|
await SyncTxHelper.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private sendResponse = async (status: SyncObjectStatus) => {
|
||||||
|
await BrowserApi.sendRuntimeMessage<SyncObjectStatus>({
|
||||||
|
type: BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT,
|
||||||
|
data: status
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private syncObj = async (obj: ObjDto, tx: BeginTxResponse) => {
|
||||||
|
switch (obj.type) {
|
||||||
|
case ObjTypeDto.PageSnapshot:
|
||||||
|
case ObjTypeDto.PageElementSnapshot: {
|
||||||
|
return await new SyncSnapshotCommand(obj as ObjDto<ObjPageDto>, tx).execute();
|
||||||
|
}
|
||||||
|
case ObjTypeDto.PageElementPin: {
|
||||||
|
return await new SyncPinCommand(obj as ObjDto<ObjPinDto>, tx).execute();
|
||||||
|
}
|
||||||
|
case ObjTypeDto.Pdf: {
|
||||||
|
return await new SyncPdfCommand(obj as ObjDto<ObjPdfDto>, tx).execute();
|
||||||
|
}
|
||||||
|
case ObjTypeDto.Note: {
|
||||||
|
return await new SyncNoteCommand(obj as ObjDto<ObjNoteDto>, tx).execute();
|
||||||
|
}
|
||||||
|
case ObjTypeDto.PageNote: {
|
||||||
|
return await new SyncPageNoteCommand(obj as ObjDto<ObjPageNoteDto>, tx).execute();
|
||||||
|
}
|
||||||
|
case ObjTypeDto.Removed: {
|
||||||
|
return await new SyncRemovedCommand(obj as ObjDto<ObjRemovedDto>, tx).execute();
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
fnConsoleLog('SyncObjectCommand->PROBLEM', obj, 'index', this.id);
|
||||||
|
return SyncObjectStatus.SERVER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -18,9 +18,9 @@ import { ICommand } from '../../../../common/model/shared/common.dto';
|
|||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ObjNoteDto } from '../../../../common/model/obj/obj-note.dto';
|
import { ObjNoteDto } from '../../../../common/model/obj/obj-note.dto';
|
||||||
import { SyncObjectCommand } from './sync-object.command';
|
import { SyncObjectCommand } from './sync-object.command';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
|
||||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
import { BeginTxResponse } from '../../api/store/api-store.model';
|
import { BeginTxResponse } from '../../api/store/api-store.model';
|
||||||
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
|
|
||||||
export class SyncNoteCommand implements ICommand<Promise<SyncObjectStatus>> {
|
export class SyncNoteCommand implements ICommand<Promise<SyncObjectStatus>> {
|
||||||
constructor(private obj: ObjDto<ObjNoteDto>, private tx: BeginTxResponse) {}
|
constructor(private obj: ObjDto<ObjNoteDto>, private tx: BeginTxResponse) {}
|
||||||
|
@ -36,7 +36,7 @@ export class SyncObjectCommand implements ICommand<Promise<void>> {
|
|||||||
} else if ('code' in resp && resp.code === ApiErrorCode.SYNC_DUPLICATED_HASH) {
|
} else if ('code' in resp && resp.code === ApiErrorCode.SYNC_DUPLICATED_HASH) {
|
||||||
return await this.setByHash();
|
return await this.setByHash();
|
||||||
}
|
}
|
||||||
fnConsoleLog('SyncObjectCommand', 'tx', this.tx, 'resp', resp);
|
fnConsoleLog('SyncObjectCommand', 'tx', this.tx, 'resp', resp, 'obj', this.obj);
|
||||||
throw new Error('PROBLEM !!!!!!!!!!!!!!!');
|
throw new Error('PROBLEM !!!!!!!!!!!!!!!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto';
|
|||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ObjPageNoteDto } from '../../../../common/model/obj/obj-note.dto';
|
import { ObjPageNoteDto } from '../../../../common/model/obj/obj-note.dto';
|
||||||
import { SyncObjectCommand } from './sync-object.command';
|
import { SyncObjectCommand } from './sync-object.command';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
||||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||||
@ -41,10 +41,9 @@ export class SyncPageNoteCommand implements ICommand<Promise<SyncObjectStatus>>
|
|||||||
private async syncNote(data: ObjPageNoteDto): Promise<void> {
|
private async syncNote(data: ObjPageNoteDto): Promise<void> {
|
||||||
const content = JSON.stringify(data);
|
const content = JSON.stringify(data);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent: data.hash,
|
|
||||||
type: SyncHashType.ObjPdfDataDto,
|
type: SyncHashType.ObjPdfDataDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: data.hash
|
||||||
}).execute();
|
}).execute();
|
||||||
if (data.prev) {
|
if (data.prev) {
|
||||||
const prevData = await BrowserStorage.get<ObjPageNoteDto>(`${ObjectStoreKeys.NOTE_HASH}:${data.prev}`);
|
const prevData = await BrowserStorage.get<ObjPageNoteDto>(`${ObjectStoreKeys.NOTE_HASH}:${data.prev}`);
|
||||||
|
@ -18,7 +18,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto';
|
|||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ObjPdfDataDto, ObjPdfDto } from '../../../../common/model/obj/obj-pdf.dto';
|
import { ObjPdfDataDto, ObjPdfDto } from '../../../../common/model/obj/obj-pdf.dto';
|
||||||
import { SyncObjectCommand } from './sync-object.command';
|
import { SyncObjectCommand } from './sync-object.command';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
||||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||||
import { BrowserStorage } from '@pinmenote/browser-api';
|
import { BrowserStorage } from '@pinmenote/browser-api';
|
||||||
@ -40,21 +40,20 @@ export class SyncPdfCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
private async syncData(data: ObjPdfDataDto, parent: string): Promise<void> {
|
private async syncData(data: ObjPdfDataDto, parent: string): Promise<void> {
|
||||||
const content = JSON.stringify(data);
|
const content = JSON.stringify(data);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjPdfDataDto,
|
type: SyncHashType.ObjPdfDataDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: data.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async syncPdf(parent: string): Promise<void> {
|
private async syncPdf(hash: string): Promise<void> {
|
||||||
const pdfData = await BrowserStorage.get<string | undefined>(`${ObjectStoreKeys.PDF_DATA}:${parent}`);
|
const pdfData = await BrowserStorage.get<string | undefined>(`${ObjectStoreKeys.PDF_DATA}:${hash}`);
|
||||||
if (!pdfData) return;
|
if (!pdfData) return;
|
||||||
await new ApiSegmentAddCommand(this.tx, pdfData, {
|
await new ApiSegmentAddCommand(this.tx, pdfData, {
|
||||||
hash: parent,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjPdf,
|
type: SyncHashType.ObjPdf,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash
|
||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto';
|
|||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ObjPinDataDto, ObjPinDescription, ObjPinDto } from '../../../../common/model/obj/obj-pin.dto';
|
import { ObjPinDataDto, ObjPinDescription, ObjPinDto } from '../../../../common/model/obj/obj-pin.dto';
|
||||||
import { SyncObjectCommand } from './sync-object.command';
|
import { SyncObjectCommand } from './sync-object.command';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
||||||
import { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.command';
|
import { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.command';
|
||||||
import { PinGetCommentCommand } from '../../../../common/command/pin/comment/pin-get-comment.command';
|
import { PinGetCommentCommand } from '../../../../common/command/pin/comment/pin-get-comment.command';
|
||||||
@ -45,10 +45,10 @@ export class SyncPinCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
if (!data) return;
|
if (!data) return;
|
||||||
const content = JSON.stringify(data);
|
const content = JSON.stringify(data);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjVideoDataDto,
|
type: SyncHashType.ObjVideoDataDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: data.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,10 +57,10 @@ export class SyncPinCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
// TODO SYNC DRAW LIKE COMMENTS
|
// TODO SYNC DRAW LIKE COMMENTS
|
||||||
const content = JSON.stringify(draw);
|
const content = JSON.stringify(draw);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: draw.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjDrawDto,
|
type: SyncHashType.ObjDrawDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: draw.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -71,10 +71,10 @@ export class SyncPinCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
if (!comment) continue;
|
if (!comment) continue;
|
||||||
const content = JSON.stringify(comment);
|
const content = JSON.stringify(comment);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: comment.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjCommentDto,
|
type: SyncHashType.ObjCommentDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: comment.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -82,20 +82,19 @@ export class SyncPinCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
private syncPinData = async (data: ObjPinDataDto) => {
|
private syncPinData = async (data: ObjPinDataDto) => {
|
||||||
const content = JSON.stringify(data);
|
const content = JSON.stringify(data);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent: data.hash,
|
|
||||||
type: SyncHashType.ObjPinDataDto,
|
type: SyncHashType.ObjPinDataDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: data.hash
|
||||||
}).execute();
|
}).execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
private syncPinDescription = async (data: ObjPinDescription, parent: string) => {
|
private syncPinDescription = async (data: ObjPinDescription, parent: string) => {
|
||||||
const content = JSON.stringify(data);
|
const content = JSON.stringify(data);
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.ObjPinDescription,
|
type: SyncHashType.ObjPinDescription,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: data.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
import { ObjDto, ObjRemovedDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto, ObjRemovedDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ICommand } from '../../../../common/model/shared/common.dto';
|
import { ICommand } from '../../../../common/model/shared/common.dto';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
import { BeginTxResponse } from '../../api/store/api-store.model';
|
import { BeginTxResponse } from '../../api/store/api-store.model';
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
|||||||
import { ObjPageDto } from '../../../../common/model/obj/obj-page.dto';
|
import { ObjPageDto } from '../../../../common/model/obj/obj-page.dto';
|
||||||
import { PageSegmentGetCommand } from '../../../../common/command/snapshot/segment/page-segment-get.command';
|
import { PageSegmentGetCommand } from '../../../../common/command/snapshot/segment/page-segment-get.command';
|
||||||
import { SyncObjectCommand } from './sync-object.command';
|
import { SyncObjectCommand } from './sync-object.command';
|
||||||
import { SyncObjectStatus } from '../sync.model';
|
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
import { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model';
|
||||||
import { PageSnapshotDto } from '../../../../common/model/obj/page-snapshot.dto';
|
import { PageSnapshotDto } from '../../../../common/model/obj/page-snapshot.dto';
|
||||||
@ -55,10 +55,10 @@ export class SyncSnapshotCommand implements ICommand<Promise<SyncObjectStatus>>
|
|||||||
const content = this.getSegmentContent(segment);
|
const content = this.getSegmentContent(segment);
|
||||||
if (!content) return;
|
if (!content) return;
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash: segment.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.PageSnapshotFirstHash,
|
type: SyncHashType.PageSnapshotFirstHash,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: segment.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
await this.syncSegmentSnapshot(segment.content as SegmentPage, parent);
|
await this.syncSegmentSnapshot(segment.content as SegmentPage, parent);
|
||||||
};
|
};
|
||||||
@ -66,17 +66,17 @@ export class SyncSnapshotCommand implements ICommand<Promise<SyncObjectStatus>>
|
|||||||
private async syncSnapshot(snapshot: PageSnapshotDto, parent: string): Promise<void> {
|
private async syncSnapshot(snapshot: PageSnapshotDto, parent: string): Promise<void> {
|
||||||
// snapshot->info
|
// snapshot->info
|
||||||
await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.info), {
|
await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.info), {
|
||||||
hash: snapshot.info.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.PageSnapshotInfoDto,
|
type: SyncHashType.PageSnapshotInfoDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: snapshot.info.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
// snapshot->data
|
// snapshot->data
|
||||||
await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.data), {
|
await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.data), {
|
||||||
hash: snapshot.data.hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: SyncHashType.PageSnapshotDataDto,
|
type: SyncHashType.PageSnapshotDataDto,
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash: snapshot.data.hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/require-await
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
@ -91,10 +91,10 @@ export class SyncSnapshotCommand implements ICommand<Promise<SyncObjectStatus>>
|
|||||||
if (!content) return;
|
if (!content) return;
|
||||||
|
|
||||||
await new ApiSegmentAddCommand(this.tx, content, {
|
await new ApiSegmentAddCommand(this.tx, content, {
|
||||||
hash,
|
key: await SyncCryptoFactory.newKey(),
|
||||||
parent,
|
|
||||||
type: this.convertSegmentTypeSyncHashType(segment.type),
|
type: this.convertSegmentTypeSyncHashType(segment.type),
|
||||||
key: await SyncCryptoFactory.newKey()
|
hash,
|
||||||
|
parent
|
||||||
}).execute();
|
}).execute();
|
||||||
|
|
||||||
switch (segment.type) {
|
switch (segment.type) {
|
||||||
|
@ -19,7 +19,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto';
|
|||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { ObjGetCommand } from '../../../../common/command/obj/obj-get.command';
|
import { ObjGetCommand } from '../../../../common/command/obj/obj-get.command';
|
||||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||||
import { SyncProgress } from '../sync.model';
|
import { SyncProgress } from '../../../../common/model/sync.model';
|
||||||
|
|
||||||
export class SyncGetProgressCommand implements ICommand<Promise<SyncProgress>> {
|
export class SyncGetProgressCommand implements ICommand<Promise<SyncProgress>> {
|
||||||
async execute(): Promise<SyncProgress> {
|
async execute(): Promise<SyncProgress> {
|
||||||
|
@ -18,13 +18,14 @@ import { BrowserStorage } from '@pinmenote/browser-api';
|
|||||||
import { ICommand } from '../../../../common/model/shared/common.dto';
|
import { ICommand } from '../../../../common/model/shared/common.dto';
|
||||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||||
import { SyncGetProgressCommand } from './sync-get-progress.command';
|
import { SyncGetProgressCommand } from './sync-get-progress.command';
|
||||||
import { SyncProgress } from '../sync.model';
|
|
||||||
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
import { ObjDto } from '../../../../common/model/obj/obj.dto';
|
||||||
import { fnDateKeyFormat } from '../../../../common/fn/fn-date-format';
|
import { fnDateKeyFormat } from '../../../../common/fn/fn-date-format';
|
||||||
import { ObjDateIndex } from '../../../../common/command/obj/index/obj-update-index-add.command';
|
import { ObjDateIndex } from '../../../../common/command/obj/index/obj-update-index-add.command';
|
||||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||||
|
import { SyncProgress } from '../../../../common/model/sync.model';
|
||||||
|
|
||||||
export class SyncResetProgressCommand implements ICommand<Promise<void>> {
|
export class SyncResetProgressCommand implements ICommand<Promise<void>> {
|
||||||
|
constructor(private refreshUpdateList = false) {}
|
||||||
async execute(): Promise<void> {
|
async execute(): Promise<void> {
|
||||||
const obj = await SyncGetProgressCommand.getFirstObject();
|
const obj = await SyncGetProgressCommand.getFirstObject();
|
||||||
const timestamp = obj?.createdAt || -1;
|
const timestamp = obj?.createdAt || -1;
|
||||||
@ -58,17 +59,20 @@ export class SyncResetProgressCommand implements ICommand<Promise<void>> {
|
|||||||
const yearMonth = fnDateKeyFormat(new Date(obj.updatedAt));
|
const yearMonth = fnDateKeyFormat(new Date(obj.updatedAt));
|
||||||
toSortSet.add(yearMonth);
|
toSortSet.add(yearMonth);
|
||||||
|
|
||||||
const updateList = await this.getList(yearMonth);
|
if (this.refreshUpdateList) await this.updateList(yearMonth, obj);
|
||||||
if (updateList.findIndex((o) => o.id === obj.id) > 0) continue;
|
|
||||||
|
|
||||||
updateList.push({ id: obj.id, dt: obj.updatedAt });
|
|
||||||
|
|
||||||
await this.setList(yearMonth, updateList);
|
|
||||||
}
|
}
|
||||||
listId -= 1;
|
listId -= 1;
|
||||||
|
fnConsoleLog('SyncResetProgressCommand', listId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort objects inside
|
// sort objects inside
|
||||||
|
if (this.refreshUpdateList) await this.sortUpdateList(toSortSet);
|
||||||
|
// clear tx
|
||||||
|
await BrowserStorage.remove(ObjectStoreKeys.SYNC_TX);
|
||||||
|
fnConsoleLog('SyncResetProgressCommand->complete in ', Date.now() - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sortUpdateList = async (toSortSet: Set<string>) => {
|
||||||
for (const yearMonth of toSortSet) {
|
for (const yearMonth of toSortSet) {
|
||||||
const list = await this.getList(yearMonth);
|
const list = await this.getList(yearMonth);
|
||||||
const s = new Set<number>();
|
const s = new Set<number>();
|
||||||
@ -88,11 +92,16 @@ export class SyncResetProgressCommand implements ICommand<Promise<void>> {
|
|||||||
});
|
});
|
||||||
await this.setList(yearMonth, newList);
|
await this.setList(yearMonth, newList);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// clear tx
|
private updateList = async (yearMonth: string, obj: ObjDto) => {
|
||||||
await BrowserStorage.remove(ObjectStoreKeys.SYNC_TX);
|
const updateList = await this.getList(yearMonth);
|
||||||
fnConsoleLog('SyncResetProgressCommand->complete in ', Date.now() - a);
|
if (updateList.findIndex((o) => o.id === obj.id) > 0) return;
|
||||||
}
|
|
||||||
|
updateList.push({ id: obj.id, dt: obj.updatedAt });
|
||||||
|
|
||||||
|
await this.setList(yearMonth, updateList);
|
||||||
|
};
|
||||||
|
|
||||||
private async setList(yearMonth: string, list: ObjDateIndex[]): Promise<void> {
|
private async setList(yearMonth: string, list: ObjDateIndex[]): Promise<void> {
|
||||||
const updateListKey = `${ObjectStoreKeys.UPDATED_DT}:${yearMonth}`;
|
const updateListKey = `${ObjectStoreKeys.UPDATED_DT}:${yearMonth}`;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { BrowserStorage } from '@pinmenote/browser-api';
|
import { BrowserStorage } from '@pinmenote/browser-api';
|
||||||
import { ICommand } from '../../../../common/model/shared/common.dto';
|
import { ICommand } from '../../../../common/model/shared/common.dto';
|
||||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||||
import { SyncProgress } from '../sync.model';
|
import { SyncProgress } from '../../../../common/model/sync.model';
|
||||||
|
|
||||||
export class SyncSetProgressCommand implements ICommand<Promise<void>> {
|
export class SyncSetProgressCommand implements ICommand<Promise<void>> {
|
||||||
constructor(protected progress: SyncProgress) {}
|
constructor(protected progress: SyncProgress) {}
|
||||||
|
@ -25,15 +25,14 @@ import { SyncNoteCommand } from './outgoing/sync-note.command';
|
|||||||
import { SyncPageNoteCommand } from './outgoing/sync-page-note.command';
|
import { SyncPageNoteCommand } from './outgoing/sync-page-note.command';
|
||||||
import { SyncPdfCommand } from './outgoing/sync-pdf.command';
|
import { SyncPdfCommand } from './outgoing/sync-pdf.command';
|
||||||
import { SyncPinCommand } from './outgoing/sync-pin.command';
|
import { SyncPinCommand } from './outgoing/sync-pin.command';
|
||||||
import { SyncObjectStatus, SyncProgress } from './sync.model';
|
import { SyncObjectStatus } from '../../../common/model/sync.model';
|
||||||
import { SyncRemovedCommand } from './outgoing/sync-removed.command';
|
import { SyncRemovedCommand } from './outgoing/sync-removed.command';
|
||||||
import { SyncSnapshotCommand } from './outgoing/sync-snapshot.command';
|
import { SyncSnapshotCommand } from './outgoing/sync-snapshot.command';
|
||||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||||
import { BeginTxResponse } from '../api/store/api-store.model';
|
import { BeginTxResponse } from '../api/store/api-store.model';
|
||||||
import { fnSleep } from '../../../common/fn/fn-sleep';
|
|
||||||
|
|
||||||
export class SyncIndexCommand implements ICommand<Promise<SyncObjectStatus>> {
|
export class SyncIndexCommand implements ICommand<Promise<SyncObjectStatus>> {
|
||||||
constructor(private progress: SyncProgress, private tx: BeginTxResponse, private id: number) {}
|
constructor(private tx: BeginTxResponse, private id: number) {}
|
||||||
|
|
||||||
async execute(): Promise<SyncObjectStatus> {
|
async execute(): Promise<SyncObjectStatus> {
|
||||||
const obj = await new ObjGetCommand(this.id).execute();
|
const obj = await new ObjGetCommand(this.id).execute();
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { SyncIndexCommand } from './sync-index.command';
|
import { SyncIndexCommand } from './sync-index.command';
|
||||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||||
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
|
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
|
||||||
import { SyncObjectStatus, SyncProgress } from './sync.model';
|
import { SyncObjectStatus, SyncProgress } from '../../../common/model/sync.model';
|
||||||
import { SyncTxHelper } from './sync-tx.helper';
|
import { SyncTxHelper } from './sync-tx.helper';
|
||||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||||
import { ObjDateIndex } from '../../../common/command/obj/index/obj-update-index-add.command';
|
import { ObjDateIndex } from '../../../common/command/obj/index/obj-update-index-add.command';
|
||||||
@ -56,7 +56,7 @@ export class SyncMonthCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||||||
let i = start;
|
let i = start;
|
||||||
let status = SyncObjectStatus.OK;
|
let status = SyncObjectStatus.OK;
|
||||||
for (i; i < indexList.length; i++) {
|
for (i; i < indexList.length; i++) {
|
||||||
status = await new SyncIndexCommand(this.progress, begin, indexList[i].id).execute();
|
status = await new SyncIndexCommand(begin, indexList[i].id).execute();
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SyncObjectStatus.SERVER_ERROR: {
|
case SyncObjectStatus.SERVER_ERROR: {
|
||||||
fnConsoleLog('SERVER_ERROR !!!!!!!!!!!!!!!!!!!');
|
fnConsoleLog('SERVER_ERROR !!!!!!!!!!!!!!!!!!!');
|
||||||
|
@ -18,7 +18,7 @@ import { fnDateToMonthFirstDay, fnMonthLastDay } from '../../../common/fn/fn-dat
|
|||||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||||
import { SyncGetProgressCommand } from './progress/sync-get-progress.command';
|
import { SyncGetProgressCommand } from './progress/sync-get-progress.command';
|
||||||
import { SyncMonthCommand } from './sync-month.command';
|
import { SyncMonthCommand } from './sync-month.command';
|
||||||
import { SyncProgress } from './sync.model';
|
import { SyncProgress } from '../../../common/model/sync.model';
|
||||||
import { SyncTxHelper } from './sync-tx.helper';
|
import { SyncTxHelper } from './sync-tx.helper';
|
||||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||||
import { fnDateKeyFormat } from '../../../common/fn/fn-date-format';
|
import { fnDateKeyFormat } from '../../../common/fn/fn-date-format';
|
||||||
@ -34,16 +34,13 @@ export class SyncServerCommand implements ICommand<Promise<void>> {
|
|||||||
if (SyncServerCommand.isInSync) return;
|
if (SyncServerCommand.isInSync) return;
|
||||||
if (!(await SyncTxHelper.shouldSync())) return;
|
if (!(await SyncTxHelper.shouldSync())) return;
|
||||||
try {
|
try {
|
||||||
// await new SyncResetProgressCommand().execute();
|
await new SyncResetProgressCommand(false).execute();
|
||||||
|
|
||||||
/*const token = await new TokenStorageGetCommand().execute();
|
|
||||||
if (token) console.log(jwtDecode<TokenDataDto>(token.access_token));*/
|
|
||||||
|
|
||||||
SyncServerCommand.isInSync = true;
|
SyncServerCommand.isInSync = true;
|
||||||
|
|
||||||
const a = Date.now();
|
const a = Date.now();
|
||||||
const progress = await new SyncGetProgressCommand().execute();
|
const progress = await new SyncGetProgressCommand().execute();
|
||||||
await this.syncOutgoing(progress);
|
// await this.syncOutgoing(progress);
|
||||||
await this.syncIncoming(progress);
|
await this.syncIncoming(progress);
|
||||||
|
|
||||||
fnConsoleLog('SyncServerCommand->execute', progress, 'in', Date.now() - a);
|
fnConsoleLog('SyncServerCommand->execute', progress, 'in', Date.now() - a);
|
||||||
@ -53,9 +50,9 @@ export class SyncServerCommand implements ICommand<Promise<void>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async syncIncoming(progress: SyncProgress): Promise<void> {
|
private async syncIncoming(progress: SyncProgress): Promise<void> {
|
||||||
fnConsoleLog('SyncServerCommand->syncIncoming');
|
|
||||||
const changesResp = await new ApiObjGetChangesCommand(progress.serverId).execute();
|
const changesResp = await new ApiObjGetChangesCommand(progress.serverId).execute();
|
||||||
if (!changesResp) return;
|
fnConsoleLog('SyncServerCommand->syncIncoming', changesResp);
|
||||||
|
if ('code' in changesResp) return;
|
||||||
for (let i = 0; i < changesResp.data.length; i++) {
|
for (let i = 0; i < changesResp.data.length; i++) {
|
||||||
const change = changesResp.data[i];
|
const change = changesResp.data[i];
|
||||||
if (progress.serverId > change.serverId) continue;
|
if (progress.serverId > change.serverId) continue;
|
||||||
@ -69,9 +66,11 @@ export class SyncServerCommand implements ICommand<Promise<void>> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fnConsoleLog('SyncServerCommand->syncIncoming->COMPLETE !!!');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async syncOutgoing(progress: SyncProgress): Promise<void> {
|
private async syncOutgoing(progress: SyncProgress): Promise<void> {
|
||||||
|
fnConsoleLog('SyncServerCommand->syncOutgoing');
|
||||||
// Empty list - fresh install
|
// Empty list - fresh install
|
||||||
if (progress.id == -1) return;
|
if (progress.id == -1) return;
|
||||||
const dt = fnDateToMonthFirstDay(new Date(progress.timestamp));
|
const dt = fnDateToMonthFirstDay(new Date(progress.timestamp));
|
||||||
@ -88,5 +87,6 @@ export class SyncServerCommand implements ICommand<Promise<void>> {
|
|||||||
|
|
||||||
dt.setMonth(dt.getMonth() + 1);
|
dt.setMonth(dt.getMonth() + 1);
|
||||||
}
|
}
|
||||||
|
fnConsoleLog('SyncServerCommand->syncOutgoing->COMPLETE !!!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import { SwInitSettingsCommand } from './command/sw/sw-init-settings.command';
|
|||||||
import { SyncServerCommand } from './command/sync/sync-server.command';
|
import { SyncServerCommand } from './command/sync/sync-server.command';
|
||||||
import { TaskExecutor } from './task/task.executor';
|
import { TaskExecutor } from './task/task.executor';
|
||||||
import { fnConsoleLog } from '../common/fn/fn-console';
|
import { fnConsoleLog } from '../common/fn/fn-console';
|
||||||
|
import { SyncManualOutgoingCommand } from './command/sync/manual/sync-manual-outgoing.command';
|
||||||
|
|
||||||
const handleMessage = async (
|
const handleMessage = async (
|
||||||
msg: BusMessage<any>,
|
msg: BusMessage<any>,
|
||||||
@ -93,6 +94,10 @@ const handleMessage = async (
|
|||||||
case BusMessageType.POPUP_SERVER_QUOTA:
|
case BusMessageType.POPUP_SERVER_QUOTA:
|
||||||
await new PopupServerQuotaCommand().execute();
|
await new PopupServerQuotaCommand().execute();
|
||||||
break;
|
break;
|
||||||
|
case BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT: {
|
||||||
|
await new SyncManualOutgoingCommand(msg.data).execute();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BusMessageType.IFRAME_INDEX:
|
case BusMessageType.IFRAME_INDEX:
|
||||||
case BusMessageType.IFRAME_INDEX_REGISTER:
|
case BusMessageType.IFRAME_INDEX_REGISTER:
|
||||||
case BusMessageType.IFRAME_START_LISTENERS:
|
case BusMessageType.IFRAME_START_LISTENERS:
|
||||||
@ -109,9 +114,11 @@ const handleMessage = async (
|
|||||||
}
|
}
|
||||||
// Sync command
|
// Sync command
|
||||||
if (
|
if (
|
||||||
![PageComputeMessage.CONTENT_FETCH_CSS, PageComputeMessage.CONTENT_FETCH_IMAGE].includes(
|
![
|
||||||
msg.type as PageComputeMessage
|
PageComputeMessage.CONTENT_FETCH_CSS,
|
||||||
)
|
PageComputeMessage.CONTENT_FETCH_IMAGE,
|
||||||
|
BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT
|
||||||
|
].includes(msg.type as any)
|
||||||
) {
|
) {
|
||||||
await new SyncServerCommand().execute();
|
await new SyncServerCommand().execute();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user