From 50b27e731e2796683db4ef881b8e5d6ca0631c24 Mon Sep 17 00:00:00 2001 From: Michal Szczepanski Date: Mon, 25 Sep 2023 23:41:14 +0200 Subject: [PATCH] fix: sync image - add mimeType, add manual sync in options-ui --- .../segment/page-segment-add-ref.command.ts | 2 - .../segment/page-segment-add.command.ts | 2 +- src/common/model/bus.model.ts | 2 + .../sync => common/model}/sync.model.ts | 0 .../account/account-details.component.tsx | 4 +- .../preview/html-preview-header.component.tsx | 100 ++++++++++++++++++ .../preview/html-preview.component.tsx | 99 ++++++----------- .../api/store/api-store-commit.command.ts | 1 - .../command/api/store/api-store.model.ts | 3 +- .../store/obj/api-obj-get-changes.command.ts | 29 +++-- .../store/segment/api-segment-add.command.ts | 27 +++-- .../store/segment/api-segment-get.command.ts | 5 +- .../segment/api-segment-quota-get.command.ts | 35 +++--- .../popup/popup-server-quota.command.ts | 10 +- .../sync-snapshot-incoming.command.ts | 10 +- .../manual/sync-manual-outgoing.command.ts | 93 ++++++++++++++++ .../sync/outgoing/sync-note.command.ts | 2 +- .../sync/outgoing/sync-object.command.ts | 2 +- .../sync/outgoing/sync-page-note.command.ts | 7 +- .../command/sync/outgoing/sync-pdf.command.ts | 17 ++- .../command/sync/outgoing/sync-pin.command.ts | 31 +++--- .../sync/outgoing/sync-removed.command.ts | 2 +- .../sync/outgoing/sync-snapshot.command.ts | 26 ++--- .../progress/sync-get-progress.command.ts | 2 +- .../progress/sync-reset-progress.command.ts | 31 ++++-- .../progress/sync-set-progress.command.ts | 2 +- .../command/sync/sync-index.command.ts | 5 +- .../command/sync/sync-month.command.ts | 4 +- .../command/sync/sync-server.command.ts | 16 +-- src/service-worker/service-worker.ts | 13 ++- 30 files changed, 392 insertions(+), 190 deletions(-) rename src/{service-worker/command/sync => common/model}/sync.model.ts (100%) create mode 100644 src/options-ui/components/preview/html-preview-header.component.tsx create mode 100644 src/service-worker/command/sync/manual/sync-manual-outgoing.command.ts diff --git a/src/common/command/snapshot/segment/page-segment-add-ref.command.ts b/src/common/command/snapshot/segment/page-segment-add-ref.command.ts index c12a1f9..00a5451 100644 --- a/src/common/command/snapshot/segment/page-segment-add-ref.command.ts +++ b/src/common/command/snapshot/segment/page-segment-add-ref.command.ts @@ -17,8 +17,6 @@ import { BrowserStorage } from '@pinmenote/browser-api'; import { ICommand } from '../../../model/shared/common.dto'; import { ObjectStoreKeys } from '../../../keys/object.store.keys'; -import { SegmentData } from '@pinmenote/page-compute'; -import { fnConsoleLog } from '../../../fn/fn-console'; export class PageSegmentAddRefCommand implements ICommand> { constructor(private hash: string) {} diff --git a/src/common/command/snapshot/segment/page-segment-add.command.ts b/src/common/command/snapshot/segment/page-segment-add.command.ts index 9ebe1c5..db96344 100644 --- a/src/common/command/snapshot/segment/page-segment-add.command.ts +++ b/src/common/command/snapshot/segment/page-segment-add.command.ts @@ -33,7 +33,7 @@ export class PageSegmentAddCommand implements ICommand> { const key = `${ObjectStoreKeys.CONTENT_HASH_COUNT}:${this.content.hash}`; let count = (await BrowserStorage.get(key)) || 0; count++; - fnConsoleLog('PageSegmentAddCommand->incrementCount', count); + // fnConsoleLog('PageSegmentAddCommand->incrementCount', count); await BrowserStorage.set(key, count); } } diff --git a/src/common/model/bus.model.ts b/src/common/model/bus.model.ts index 0fef7c1..123fa4c 100644 --- a/src/common/model/bus.model.ts +++ b/src/common/model/bus.model.ts @@ -56,6 +56,8 @@ export enum BusMessageType { CONTENT_TAKE_SCREENSHOT = 'content.take.screenshot', CONTENT_FETCH_PDF = 'content.fetch.pdf', CONTENT_THEME = 'content.theme', + // Iframe + OPTIONS_SYNC_OUTGOING_OBJECT = 'options.sync.outgoing.object', // Iframe content script IFRAME_INDEX = 'iframe.index', IFRAME_INDEX_REGISTER = 'iframe.index.register', diff --git a/src/service-worker/command/sync/sync.model.ts b/src/common/model/sync.model.ts similarity index 100% rename from src/service-worker/command/sync/sync.model.ts rename to src/common/model/sync.model.ts diff --git a/src/default-popup/components/account/account-details.component.tsx b/src/default-popup/components/account/account-details.component.tsx index b6cdd05..fbc073f 100644 --- a/src/default-popup/components/account/account-details.component.tsx +++ b/src/default-popup/components/account/account-details.component.tsx @@ -48,9 +48,11 @@ export const AccountDetailsComponent: FunctionComponent = (props) => { if (PopupTokenStore.token) { setTokenData(jwtDecode(PopupTokenStore.token.access_token)); - quotaKey = dispatcher.addListener( + quotaKey = dispatcher.addListener( BusMessageType.POPUP_SERVER_QUOTA, (event, key, value) => { + // TODO fix server error handling + if ('code' in value) return; LogManager.log(`${event} - ${JSON.stringify(value)}`); setServerQuota(value); }, diff --git a/src/options-ui/components/preview/html-preview-header.component.tsx b/src/options-ui/components/preview/html-preview-header.component.tsx new file mode 100644 index 0000000..c682543 --- /dev/null +++ b/src/options-ui/components/preview/html-preview-header.component.tsx @@ -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 . + */ +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; + isLoading: boolean; + handleDownload: () => void; + handleClose: () => void; +} + +export const HtmlPreviewHeaderComponent: FunctionComponent = (props) => { + const titleRef = useRef(null); + const urlRef = useRef(null); + useEffect(() => { + if (!titleRef.current) return; + if (!urlRef.current) return; + if (props.obj) renderHeader(props.obj); + const dispatcher = TinyDispatcher.getInstance(); + const syncKey = dispatcher.addListener( + 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): void => { + const snapshot: PageSnapshotDto = obj.data.snapshot; + if (titleRef.current) { + titleRef.current.innerHTML = snapshot.info.title; + } + if (urlRef.current) { + urlRef.current.innerHTML = ` + + ${snapshot.info.url.href} + Created At : ${dayjs(obj.createdAt).format(DATE_YEAR_SECOND)}`; + } + }; + + const handleManualSync = async () => { + await BrowserApi.sendRuntimeMessage({ type: BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT, data: props.obj?.id }); + }; + + return ( +
+
+

+
+
+
+
+ +
+ + + + + + + + + +
+
+ ); +}; diff --git a/src/options-ui/components/preview/html-preview.component.tsx b/src/options-ui/components/preview/html-preview.component.tsx index 8edf752..7bef084 100644 --- a/src/options-ui/components/preview/html-preview.component.tsx +++ b/src/options-ui/components/preview/html-preview.component.tsx @@ -19,10 +19,6 @@ import React, { FunctionComponent, useEffect, useRef, useState } from 'react'; import { SegmentImg, SegmentPage, SegmentType } from '@pinmenote/page-compute'; import { BrowserApi } from '@pinmenote/browser-api'; 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 { LinkHrefStore } from '../../../common/store/link-href.store'; 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 { SettingsStore } from '../../store/settings.store'; import { XpathFactory } from '../../../common/factory/xpath.factory'; -import dayjs from 'dayjs'; import { fnConsoleLog } from '../../../common/fn/fn-console'; import { fnSleep } from '../../../common/fn/fn-sleep'; import { fnUid } from '../../../common/fn/fn-uid'; +import { HtmlPreviewHeaderComponent } from './html-preview-header.component'; interface Props { visible: boolean; @@ -45,13 +41,11 @@ interface Props { export const HtmlPreviewComponent: FunctionComponent = (props) => { const containerRef = useRef(null); const htmlRef = useRef(null); - const titleRef = useRef(null); - const urlRef = useRef(null); const [visible, setVisible] = useState(props.visible); const [pageSegment, setPageSegment] = useState(); - const [pageSnapshot, setPageSnapshot] = useState(); + const [objData, setObjData] = useState | undefined>(); const [isLoading, setIsLoading] = useState(false); const [isPreLoading, setIsPreLoading] = useState(true); @@ -62,37 +56,33 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { if (!idhash[0].startsWith('#obj')) return; try { 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) { fnConsoleLog('Error render or parseInt', e); } } - }); + }, [props]); - const render = (id: number) => { - if (titleRef.current) titleRef.current.innerHTML = ''; - if (urlRef.current) urlRef.current.innerHTML = ''; - setTimeout(async () => { - setIsPreLoading(true); - setIsLoading(true); - const obj = await new ObjGetCommand(id).execute(); - setPageSnapshot(obj.data.snapshot); - const pageSegment = await new PageSegmentGetCommand(obj.data.snapshot.segment).execute(); - if (pageSegment) { - setPageSegment(pageSegment.content); - } else { - fnConsoleLog('NOT FOUND ', obj.data.snapshot, 'hash', obj.data.snapshot.segment); - } - if (obj.data.snapshot.data.canvas) { - renderCanvas(obj); - } else { - await renderSnapshot(obj, pageSegment?.content); - } - if (obj.type === ObjTypeDto.PageSnapshot) { - const pinIds = await LinkHrefStore.pinIds(obj.data.snapshot.info.url.href); - await renderPins(pinIds); - } - }); + const render = async (id: number) => { + setIsPreLoading(true); + setIsLoading(true); + const obj = await new ObjGetCommand(id).execute(); + setObjData(obj); + const pageSegment = await new PageSegmentGetCommand(obj.data.snapshot.segment).execute(); + if (pageSegment) { + setPageSegment(pageSegment.content); + } else { + fnConsoleLog('NOT FOUND ', obj.data.snapshot, 'hash', obj.data.snapshot.segment); + } + if (obj.data.snapshot.data.canvas) { + renderCanvas(obj); + } else { + await renderSnapshot(obj, pageSegment?.content); + } + if (obj.type === ObjTypeDto.PageSnapshot) { + const pinIds = await LinkHrefStore.pinIds(obj.data.snapshot.info.url.href); + await renderPins(pinIds); + } }; const renderPins = async (ids: number[]) => { @@ -160,8 +150,6 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { const renderCanvas = (obj: ObjDto, content?: SegmentPage) => { const snapshot: PageSnapshotDto = obj.data.snapshot; - renderHeader(obj); - if (!htmlRef.current) return; if (!containerRef.current) return; const iframe = document.createElement('iframe'); @@ -187,7 +175,6 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { const renderSnapshot = async (obj: ObjDto, segment?: SegmentPage): Promise => { const snapshot: PageSnapshotDto = obj.data.snapshot; - renderHeader(obj); if (!htmlRef.current) return; if (!containerRef.current) return; if (!segment) return; @@ -210,19 +197,6 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { setIsLoading(false); }; - const renderHeader = (obj: ObjDto): void => { - const snapshot: PageSnapshotDto = obj.data.snapshot; - if (titleRef.current) { - titleRef.current.innerHTML = snapshot.info.title; - } - if (urlRef.current) { - urlRef.current.innerHTML = ` - - ${snapshot.info.url.href} - Created At : ${dayjs(obj.createdAt).format(DATE_YEAR_SECOND)}`; - } - }; - const writeDoc = async (doc: Document, html: string, assets: string[], cleanLoader = false): Promise => { doc.write(html); doc.close(); @@ -310,7 +284,7 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { }; const handleDownload = async () => { - if (!pageSegment || !pageSnapshot) return; + if (!pageSegment || !objData) return; if (!htmlRef.current) return; const iframe = htmlRef.current.lastChild as HTMLIFrameElement; // TODO gather all iframe hashes and pass here with content @@ -347,23 +321,12 @@ export const HtmlPreviewComponent: FunctionComponent = (props) => { left: '0px' }} > -
-
-

-
-
-
-
- -
- - - - - - -
-
+
response', resp); return resp.ok; } catch (e) { fnConsoleLog('ApiStoreBeginCommand->Error', e); diff --git a/src/service-worker/command/api/store/api-store.model.ts b/src/service-worker/command/api/store/api-store.model.ts index a41c3f9..72ebed7 100644 --- a/src/service-worker/command/api/store/api-store.model.ts +++ b/src/service-worker/command/api/store/api-store.model.ts @@ -58,8 +58,9 @@ export enum SyncHashType { } export interface SegmentSingleHash { - hash: string; type: SyncHashType; + hash: string; + mimeType?: string; } export interface SegmentHashListResponse { diff --git a/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts b/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts index eccd306..4ebbeee 100644 --- a/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts +++ b/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts @@ -16,27 +16,36 @@ */ import { ApiCallBase } from '../../api-call.base'; 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 { ObjChangesResponse } from '../api-store.model'; +import { ApiErrorCode } from '../../../../../common/model/shared/api.error-code'; -export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand> { - constructor(private serverId?: number) { +const errorResponse: ServerErrorDto = { code: ApiErrorCode.INTERNAL, message: 'Send request problem' }; + +export class ApiObjGetChangesCommand + extends ApiCallBase + implements ICommand> +{ + constructor(private serverId: number) { super(); } - async execute(): Promise { + async execute(): Promise { await this.initTokenData(); - if (!this.storeUrl) return; + if (!this.storeUrl) return errorResponse; try { - const resp = await FetchService.fetch( - `${this.storeUrl}/api/v1/obj/changes?serverId=${this.serverId || 0}`, + const resp = await FetchService.fetch( + `${this.storeUrl}/api/v1/obj/changes?serverId=${this.serverId}`, { headers: this.getAuthHeaders() }, this.refreshParams() ); - fnConsoleLog('ApiStoreChangesCommand->response', resp); - return resp.data; + if (resp.status === 200) return resp.data; + fnConsoleLog(resp); + errorResponse.message = (resp.data as ServerErrorDto).message; + return errorResponse; } catch (e) { - fnConsoleLog('ApiStoreChangesCommand->Error', e); + fnConsoleLog('ApiObjGetChangesCommand->Error', e); } + return errorResponse; } } diff --git a/src/service-worker/command/api/store/segment/api-segment-add.command.ts b/src/service-worker/command/api/store/segment/api-segment-add.command.ts index ae6e634..968715a 100644 --- a/src/service-worker/command/api/store/segment/api-segment-add.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-add.command.ts @@ -36,15 +36,16 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand { await this.initTokenData(); if (!this.storeUrl) return false; - if (await this.hasSegment()) return true; - return await this.addSegment(); + // if (await this.hasSegment(this.storeUrl)) return true; + return await this.addSegment(this.storeUrl); } - async hasSegment(): Promise { + async hasSegment(storeUrl: string): Promise { + if (!this.storeUrl) return false; const authHeaders = this.getAuthHeaders(); const params = this.data.parent ? `?parent=${this.data.parent}` : ''; const resp = await FetchService.fetch( - `${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', headers: { @@ -56,22 +57,26 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand { + async addSegment(storeUrl: string): Promise { const formData = new FormData(); if (this.data.type.toString() === SyncHashType.Img) { 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' })); } else { try { - formData.append('file', fnB64toBlob(this.file)); + const blob = fnB64toBlob(this.file); + formData.append('mimeType', blob.type); + formData.append('file', blob); } catch (e) { - console.log(this.file, this.data, e); - throw new Error('aaaaaaaaaaaaaaaaaaaaa'); + fnConsoleLog(this.file, this.data, e); + throw new Error('ApiSegmentAddCommand->addSegment->Error->Img->base64'); } } } 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 { const fileData = deflate(this.file); formData.append('file', new Blob([fileData], { type: 'application/zip' })); @@ -85,7 +90,7 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand> { - constructor(private hash: string) { + constructor(private hash: string, private mimeType?: string) { super(); } async execute(): Promise { await this.initTokenData(); if (!this.storeUrl) return; try { + const mimeType = this.mimeType ? `?mimeType=${encodeURI(this.mimeType)}` : ''; const resp = await FetchService.fetch( - `${this.storeUrl}/api/v1/segment/${this.hash}`, + `${this.storeUrl}/api/v1/segment/${this.hash}${mimeType}`, { headers: this.getAuthHeaders(), type: 'BLOB' }, this.refreshParams() ); diff --git a/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts b/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts index 7ef097f..71d20b0 100644 --- a/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts @@ -16,23 +16,34 @@ */ import { ApiCallBase } from '../../api-call.base'; 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 { ApiErrorCode } from '../../../../../common/model/shared/api.error-code'; +import { fnConsoleLog } from '../../../../../common/fn/fn-console'; -export class ApiSegmentQuotaGetCommand extends ApiCallBase implements ICommand> { +export class ApiSegmentQuotaGetCommand + extends ApiCallBase + implements ICommand> +{ constructor() { super(); } - async execute(): Promise { + async execute(): Promise { await this.initTokenData(); - const resp = await FetchService.fetch( - `${this.storeUrl!}/api/v1/segment/quota`, - { - type: 'JSON', - headers: this.getAuthHeaders(true) - }, - this.refreshParams() - ); - return resp.data; + if (!this.storeUrl) return { code: ApiErrorCode.INTERNAL, message: 'ApiSegmentQuotaGetCommand' }; + try { + const resp = await FetchService.fetch( + `${this.storeUrl}/api/v1/segment/quota`, + { + type: 'JSON', + headers: this.getAuthHeaders(true) + }, + this.refreshParams() + ); + return resp.data; + } catch (e) { + fnConsoleLog('ApiSegmentQuotaGetCommand', e); + } + return { code: ApiErrorCode.INTERNAL, message: 'ApiSegmentQuotaGetCommand' }; } } diff --git a/src/service-worker/command/popup/popup-server-quota.command.ts b/src/service-worker/command/popup/popup-server-quota.command.ts index bcec9ea..7d789ad 100644 --- a/src/service-worker/command/popup/popup-server-quota.command.ts +++ b/src/service-worker/command/popup/popup-server-quota.command.ts @@ -14,14 +14,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -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 { 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> { async execute(): Promise { const data = await new ApiSegmentQuotaGetCommand().execute(); - await BrowserApi.sendRuntimeMessage({ type: BusMessageType.POPUP_SERVER_QUOTA, data }); + await BrowserApi.sendRuntimeMessage({ + type: BusMessageType.POPUP_SERVER_QUOTA, + data + }); } } diff --git a/src/service-worker/command/sync/incoming/sync-snapshot-incoming.command.ts b/src/service-worker/command/sync/incoming/sync-snapshot-incoming.command.ts index 9dd2188..0e19aa9 100644 --- a/src/service-worker/command/sync/incoming/sync-snapshot-incoming.command.ts +++ b/src/service-worker/command/sync/incoming/sync-snapshot-incoming.command.ts @@ -50,7 +50,7 @@ export class SyncSnapshotIncomingCommand implements ICommand> { if (!hashList) return false; const pageSnapshot = await this.getSnapshot(hashList); if (!pageSnapshot) { - fnConsoleLog('SyncSnapshotIncomingCommand->execute PROBLEM !!!!!!!!!!!!!!!!!!!', this.change); + fnConsoleLog('SyncSnapshotIncomingCommand->execute PROBLEM !!!!!!!!!!!!!!!!!!!', this.change, hashList); return false; } // sleep 1s for now @@ -108,7 +108,7 @@ export class SyncSnapshotIncomingCommand implements ICommand> { let info: PageSnapshotInfoDto | undefined; let segment: string | undefined = undefined; 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; switch (child.type.toString()) { case SyncHashType.Img: { @@ -117,10 +117,13 @@ export class SyncSnapshotIncomingCommand implements ICommand> { let src = 'data:'; try { src = await UrlFactory.toDataUri(segmentData); + // @vane WORKAROUND FIX convert image/svg -> image/svg+xml to render correctly inside tag + const check = 'data:image/svg'; + if (src.startsWith(check)) src = 'data:image/svg+xml' + src.substring(check.length); } catch (e) { const buffer = await segmentData.arrayBuffer(); const textData = new TextDecoder().decode(buffer); - console.log('ERROR !!!!!!!!! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa !!!!!!!!!!!!!!!!!!!!!!!!!!!', textData); + fnConsoleLog('SyncSnapshotIncomingCommand->getSnapshot->Img->Error !!!', textData); } const content: SegmentImg = { src }; await new PageSegmentAddCommand({ type: SegmentType.IMG, hash: child.hash, content }).execute(); @@ -162,7 +165,6 @@ export class SyncSnapshotIncomingCommand implements ICommand> { segment = child.hash; const content = await this.getString(segmentData); const html: SegmentHtml = JSON.parse(content); - fnConsoleLog('SyncSnapshotIncomingCommand->getSnapshot->PageSnapshotFirstHash', html, child.hash); await new PageSegmentAddCommand({ type: SegmentType.SNAPSHOT, content: html, diff --git a/src/service-worker/command/sync/manual/sync-manual-outgoing.command.ts b/src/service-worker/command/sync/manual/sync-manual-outgoing.command.ts new file mode 100644 index 0000000..cdee868 --- /dev/null +++ b/src/service-worker/command/sync/manual/sync-manual-outgoing.command.ts @@ -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 . + */ +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> { + constructor(private id: number) {} + async execute(): Promise { + 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({ + 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, tx).execute(); + } + case ObjTypeDto.PageElementPin: { + return await new SyncPinCommand(obj as ObjDto, tx).execute(); + } + case ObjTypeDto.Pdf: { + return await new SyncPdfCommand(obj as ObjDto, tx).execute(); + } + case ObjTypeDto.Note: { + return await new SyncNoteCommand(obj as ObjDto, tx).execute(); + } + case ObjTypeDto.PageNote: { + return await new SyncPageNoteCommand(obj as ObjDto, tx).execute(); + } + case ObjTypeDto.Removed: { + return await new SyncRemovedCommand(obj as ObjDto, tx).execute(); + } + default: { + fnConsoleLog('SyncObjectCommand->PROBLEM', obj, 'index', this.id); + return SyncObjectStatus.SERVER_ERROR; + } + } + }; +} diff --git a/src/service-worker/command/sync/outgoing/sync-note.command.ts b/src/service-worker/command/sync/outgoing/sync-note.command.ts index 5b0ea71..8c3f926 100644 --- a/src/service-worker/command/sync/outgoing/sync-note.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-note.command.ts @@ -18,9 +18,9 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjNoteDto } from '../../../../common/model/obj/obj-note.dto'; import { SyncObjectCommand } from './sync-object.command'; -import { SyncObjectStatus } from '../sync.model'; import { fnConsoleLog } from '../../../../common/fn/fn-console'; import { BeginTxResponse } from '../../api/store/api-store.model'; +import { SyncObjectStatus } from '../../../../common/model/sync.model'; export class SyncNoteCommand implements ICommand> { constructor(private obj: ObjDto, private tx: BeginTxResponse) {} diff --git a/src/service-worker/command/sync/outgoing/sync-object.command.ts b/src/service-worker/command/sync/outgoing/sync-object.command.ts index f2254d9..6d3c57c 100644 --- a/src/service-worker/command/sync/outgoing/sync-object.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-object.command.ts @@ -36,7 +36,7 @@ export class SyncObjectCommand implements ICommand> { } else if ('code' in resp && resp.code === ApiErrorCode.SYNC_DUPLICATED_HASH) { 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 !!!!!!!!!!!!!!!'); } diff --git a/src/service-worker/command/sync/outgoing/sync-page-note.command.ts b/src/service-worker/command/sync/outgoing/sync-page-note.command.ts index 95cd109..1c9dff6 100644 --- a/src/service-worker/command/sync/outgoing/sync-page-note.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-page-note.command.ts @@ -19,7 +19,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjPageNoteDto } from '../../../../common/model/obj/obj-note.dto'; 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 { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model'; import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys'; @@ -41,10 +41,9 @@ export class SyncPageNoteCommand implements ICommand> private async syncNote(data: ObjPageNoteDto): Promise { const content = JSON.stringify(data); await new ApiSegmentAddCommand(this.tx, content, { - hash: data.hash, - parent: data.hash, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdfDataDto, - key: await SyncCryptoFactory.newKey() + hash: data.hash }).execute(); if (data.prev) { const prevData = await BrowserStorage.get(`${ObjectStoreKeys.NOTE_HASH}:${data.prev}`); diff --git a/src/service-worker/command/sync/outgoing/sync-pdf.command.ts b/src/service-worker/command/sync/outgoing/sync-pdf.command.ts index d44e6fb..7e23a96 100644 --- a/src/service-worker/command/sync/outgoing/sync-pdf.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-pdf.command.ts @@ -18,7 +18,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjPdfDataDto, ObjPdfDto } from '../../../../common/model/obj/obj-pdf.dto'; 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 { ObjectStoreKeys } from '../../../../common/keys/object.store.keys'; import { BrowserStorage } from '@pinmenote/browser-api'; @@ -40,21 +40,20 @@ export class SyncPdfCommand implements ICommand> { private async syncData(data: ObjPdfDataDto, parent: string): Promise { const content = JSON.stringify(data); await new ApiSegmentAddCommand(this.tx, content, { - hash: data.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdfDataDto, - key: await SyncCryptoFactory.newKey() + hash: data.hash, + parent }).execute(); } - private async syncPdf(parent: string): Promise { - const pdfData = await BrowserStorage.get(`${ObjectStoreKeys.PDF_DATA}:${parent}`); + private async syncPdf(hash: string): Promise { + const pdfData = await BrowserStorage.get(`${ObjectStoreKeys.PDF_DATA}:${hash}`); if (!pdfData) return; await new ApiSegmentAddCommand(this.tx, pdfData, { - hash: parent, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdf, - key: await SyncCryptoFactory.newKey() + hash }).execute(); } } diff --git a/src/service-worker/command/sync/outgoing/sync-pin.command.ts b/src/service-worker/command/sync/outgoing/sync-pin.command.ts index e2e76a8..be5bc50 100644 --- a/src/service-worker/command/sync/outgoing/sync-pin.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-pin.command.ts @@ -18,7 +18,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjPinDataDto, ObjPinDescription, ObjPinDto } from '../../../../common/model/obj/obj-pin.dto'; 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 { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.command'; import { PinGetCommentCommand } from '../../../../common/command/pin/comment/pin-get-comment.command'; @@ -45,10 +45,10 @@ export class SyncPinCommand implements ICommand> { if (!data) return; const content = JSON.stringify(data); await new ApiSegmentAddCommand(this.tx, content, { - hash: data.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjVideoDataDto, - key: await SyncCryptoFactory.newKey() + hash: data.hash, + parent }).execute(); }; @@ -57,10 +57,10 @@ export class SyncPinCommand implements ICommand> { // TODO SYNC DRAW LIKE COMMENTS const content = JSON.stringify(draw); await new ApiSegmentAddCommand(this.tx, content, { - hash: draw.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjDrawDto, - key: await SyncCryptoFactory.newKey() + hash: draw.hash, + parent }).execute(); } }; @@ -71,10 +71,10 @@ export class SyncPinCommand implements ICommand> { if (!comment) continue; const content = JSON.stringify(comment); await new ApiSegmentAddCommand(this.tx, content, { - hash: comment.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjCommentDto, - key: await SyncCryptoFactory.newKey() + hash: comment.hash, + parent }).execute(); } }; @@ -82,20 +82,19 @@ export class SyncPinCommand implements ICommand> { private syncPinData = async (data: ObjPinDataDto) => { const content = JSON.stringify(data); await new ApiSegmentAddCommand(this.tx, content, { - hash: data.hash, - parent: data.hash, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPinDataDto, - key: await SyncCryptoFactory.newKey() + hash: data.hash }).execute(); }; private syncPinDescription = async (data: ObjPinDescription, parent: string) => { const content = JSON.stringify(data); await new ApiSegmentAddCommand(this.tx, content, { - hash: data.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPinDescription, - key: await SyncCryptoFactory.newKey() + hash: data.hash, + parent }).execute(); }; } diff --git a/src/service-worker/command/sync/outgoing/sync-removed.command.ts b/src/service-worker/command/sync/outgoing/sync-removed.command.ts index 6c8f18d..355d6b5 100644 --- a/src/service-worker/command/sync/outgoing/sync-removed.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-removed.command.ts @@ -16,7 +16,7 @@ */ import { ObjDto, ObjRemovedDto } from '../../../../common/model/obj/obj.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 { BeginTxResponse } from '../../api/store/api-store.model'; diff --git a/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts b/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts index 96f2122..b83c80c 100644 --- a/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts @@ -20,7 +20,7 @@ import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjPageDto } from '../../../../common/model/obj/obj-page.dto'; import { PageSegmentGetCommand } from '../../../../common/command/snapshot/segment/page-segment-get.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 { BeginTxResponse, SyncHashType } from '../../api/store/api-store.model'; import { PageSnapshotDto } from '../../../../common/model/obj/page-snapshot.dto'; @@ -55,10 +55,10 @@ export class SyncSnapshotCommand implements ICommand> const content = this.getSegmentContent(segment); if (!content) return; await new ApiSegmentAddCommand(this.tx, content, { - hash: segment.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotFirstHash, - key: await SyncCryptoFactory.newKey() + hash: segment.hash, + parent }).execute(); await this.syncSegmentSnapshot(segment.content as SegmentPage, parent); }; @@ -66,17 +66,17 @@ export class SyncSnapshotCommand implements ICommand> private async syncSnapshot(snapshot: PageSnapshotDto, parent: string): Promise { // snapshot->info await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.info), { - hash: snapshot.info.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotInfoDto, - key: await SyncCryptoFactory.newKey() + hash: snapshot.info.hash, + parent }).execute(); // snapshot->data await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.data), { - hash: snapshot.data.hash, - parent, + key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotDataDto, - key: await SyncCryptoFactory.newKey() + hash: snapshot.data.hash, + parent }).execute(); } // eslint-disable-next-line @typescript-eslint/require-await @@ -91,10 +91,10 @@ export class SyncSnapshotCommand implements ICommand> if (!content) return; await new ApiSegmentAddCommand(this.tx, content, { - hash, - parent, + key: await SyncCryptoFactory.newKey(), type: this.convertSegmentTypeSyncHashType(segment.type), - key: await SyncCryptoFactory.newKey() + hash, + parent }).execute(); switch (segment.type) { diff --git a/src/service-worker/command/sync/progress/sync-get-progress.command.ts b/src/service-worker/command/sync/progress/sync-get-progress.command.ts index d96c341..21e729e 100644 --- a/src/service-worker/command/sync/progress/sync-get-progress.command.ts +++ b/src/service-worker/command/sync/progress/sync-get-progress.command.ts @@ -19,7 +19,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjGetCommand } from '../../../../common/command/obj/obj-get.command'; 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> { async execute(): Promise { diff --git a/src/service-worker/command/sync/progress/sync-reset-progress.command.ts b/src/service-worker/command/sync/progress/sync-reset-progress.command.ts index c763b64..a8ec42e 100644 --- a/src/service-worker/command/sync/progress/sync-reset-progress.command.ts +++ b/src/service-worker/command/sync/progress/sync-reset-progress.command.ts @@ -18,13 +18,14 @@ import { BrowserStorage } from '@pinmenote/browser-api'; import { ICommand } from '../../../../common/model/shared/common.dto'; import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys'; import { SyncGetProgressCommand } from './sync-get-progress.command'; -import { SyncProgress } from '../sync.model'; import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { fnDateKeyFormat } from '../../../../common/fn/fn-date-format'; import { ObjDateIndex } from '../../../../common/command/obj/index/obj-update-index-add.command'; import { fnConsoleLog } from '../../../../common/fn/fn-console'; +import { SyncProgress } from '../../../../common/model/sync.model'; export class SyncResetProgressCommand implements ICommand> { + constructor(private refreshUpdateList = false) {} async execute(): Promise { const obj = await SyncGetProgressCommand.getFirstObject(); const timestamp = obj?.createdAt || -1; @@ -58,17 +59,20 @@ export class SyncResetProgressCommand implements ICommand> { const yearMonth = fnDateKeyFormat(new Date(obj.updatedAt)); toSortSet.add(yearMonth); - const updateList = await this.getList(yearMonth); - if (updateList.findIndex((o) => o.id === obj.id) > 0) continue; - - updateList.push({ id: obj.id, dt: obj.updatedAt }); - - await this.setList(yearMonth, updateList); + if (this.refreshUpdateList) await this.updateList(yearMonth, obj); } listId -= 1; + fnConsoleLog('SyncResetProgressCommand', listId); } // 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) => { for (const yearMonth of toSortSet) { const list = await this.getList(yearMonth); const s = new Set(); @@ -88,11 +92,16 @@ export class SyncResetProgressCommand implements ICommand> { }); await this.setList(yearMonth, newList); } + }; - // clear tx - await BrowserStorage.remove(ObjectStoreKeys.SYNC_TX); - fnConsoleLog('SyncResetProgressCommand->complete in ', Date.now() - a); - } + private updateList = async (yearMonth: string, obj: ObjDto) => { + const updateList = await this.getList(yearMonth); + 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 { const updateListKey = `${ObjectStoreKeys.UPDATED_DT}:${yearMonth}`; diff --git a/src/service-worker/command/sync/progress/sync-set-progress.command.ts b/src/service-worker/command/sync/progress/sync-set-progress.command.ts index ac7edfb..a8191b3 100644 --- a/src/service-worker/command/sync/progress/sync-set-progress.command.ts +++ b/src/service-worker/command/sync/progress/sync-set-progress.command.ts @@ -17,7 +17,7 @@ import { BrowserStorage } from '@pinmenote/browser-api'; import { ICommand } from '../../../../common/model/shared/common.dto'; 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> { constructor(protected progress: SyncProgress) {} diff --git a/src/service-worker/command/sync/sync-index.command.ts b/src/service-worker/command/sync/sync-index.command.ts index 6ad92be..b45bf35 100644 --- a/src/service-worker/command/sync/sync-index.command.ts +++ b/src/service-worker/command/sync/sync-index.command.ts @@ -25,15 +25,14 @@ import { SyncNoteCommand } from './outgoing/sync-note.command'; import { SyncPageNoteCommand } from './outgoing/sync-page-note.command'; import { SyncPdfCommand } from './outgoing/sync-pdf.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 { SyncSnapshotCommand } from './outgoing/sync-snapshot.command'; import { fnConsoleLog } from '../../../common/fn/fn-console'; import { BeginTxResponse } from '../api/store/api-store.model'; -import { fnSleep } from '../../../common/fn/fn-sleep'; export class SyncIndexCommand implements ICommand> { - constructor(private progress: SyncProgress, private tx: BeginTxResponse, private id: number) {} + constructor(private tx: BeginTxResponse, private id: number) {} async execute(): Promise { const obj = await new ObjGetCommand(this.id).execute(); diff --git a/src/service-worker/command/sync/sync-month.command.ts b/src/service-worker/command/sync/sync-month.command.ts index 72df592..41dae84 100644 --- a/src/service-worker/command/sync/sync-month.command.ts +++ b/src/service-worker/command/sync/sync-month.command.ts @@ -17,7 +17,7 @@ import { SyncIndexCommand } from './sync-index.command'; import { ICommand } from '../../../common/model/shared/common.dto'; 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 { fnConsoleLog } from '../../../common/fn/fn-console'; import { ObjDateIndex } from '../../../common/command/obj/index/obj-update-index-add.command'; @@ -56,7 +56,7 @@ export class SyncMonthCommand implements ICommand> { let i = start; let status = SyncObjectStatus.OK; 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) { case SyncObjectStatus.SERVER_ERROR: { fnConsoleLog('SERVER_ERROR !!!!!!!!!!!!!!!!!!!'); diff --git a/src/service-worker/command/sync/sync-server.command.ts b/src/service-worker/command/sync/sync-server.command.ts index d595b12..129915c 100644 --- a/src/service-worker/command/sync/sync-server.command.ts +++ b/src/service-worker/command/sync/sync-server.command.ts @@ -18,7 +18,7 @@ import { fnDateToMonthFirstDay, fnMonthLastDay } from '../../../common/fn/fn-dat import { ICommand } from '../../../common/model/shared/common.dto'; import { SyncGetProgressCommand } from './progress/sync-get-progress.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 { fnConsoleLog } from '../../../common/fn/fn-console'; import { fnDateKeyFormat } from '../../../common/fn/fn-date-format'; @@ -34,16 +34,13 @@ export class SyncServerCommand implements ICommand> { if (SyncServerCommand.isInSync) return; if (!(await SyncTxHelper.shouldSync())) return; try { - // await new SyncResetProgressCommand().execute(); - - /*const token = await new TokenStorageGetCommand().execute(); - if (token) console.log(jwtDecode(token.access_token));*/ + await new SyncResetProgressCommand(false).execute(); SyncServerCommand.isInSync = true; const a = Date.now(); const progress = await new SyncGetProgressCommand().execute(); - await this.syncOutgoing(progress); + // await this.syncOutgoing(progress); await this.syncIncoming(progress); fnConsoleLog('SyncServerCommand->execute', progress, 'in', Date.now() - a); @@ -53,9 +50,9 @@ export class SyncServerCommand implements ICommand> { } private async syncIncoming(progress: SyncProgress): Promise { - fnConsoleLog('SyncServerCommand->syncIncoming'); 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++) { const change = changesResp.data[i]; if (progress.serverId > change.serverId) continue; @@ -69,9 +66,11 @@ export class SyncServerCommand implements ICommand> { return; } } + fnConsoleLog('SyncServerCommand->syncIncoming->COMPLETE !!!'); } private async syncOutgoing(progress: SyncProgress): Promise { + fnConsoleLog('SyncServerCommand->syncOutgoing'); // Empty list - fresh install if (progress.id == -1) return; const dt = fnDateToMonthFirstDay(new Date(progress.timestamp)); @@ -88,5 +87,6 @@ export class SyncServerCommand implements ICommand> { dt.setMonth(dt.getMonth() + 1); } + fnConsoleLog('SyncServerCommand->syncOutgoing->COMPLETE !!!'); } } diff --git a/src/service-worker/service-worker.ts b/src/service-worker/service-worker.ts index c2b9be5..e988108 100644 --- a/src/service-worker/service-worker.ts +++ b/src/service-worker/service-worker.ts @@ -37,6 +37,7 @@ import { SwInitSettingsCommand } from './command/sw/sw-init-settings.command'; import { SyncServerCommand } from './command/sync/sync-server.command'; import { TaskExecutor } from './task/task.executor'; import { fnConsoleLog } from '../common/fn/fn-console'; +import { SyncManualOutgoingCommand } from './command/sync/manual/sync-manual-outgoing.command'; const handleMessage = async ( msg: BusMessage, @@ -93,6 +94,10 @@ const handleMessage = async ( case BusMessageType.POPUP_SERVER_QUOTA: await new PopupServerQuotaCommand().execute(); break; + case BusMessageType.OPTIONS_SYNC_OUTGOING_OBJECT: { + await new SyncManualOutgoingCommand(msg.data).execute(); + break; + } case BusMessageType.IFRAME_INDEX: case BusMessageType.IFRAME_INDEX_REGISTER: case BusMessageType.IFRAME_START_LISTENERS: @@ -109,9 +114,11 @@ const handleMessage = async ( } // Sync command 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(); }